Less Paper - iOS client for Paperless-ngx
6
stars
96
commits
Swift
primary language
Sep 6, 2026
updated
A native iOS client for paperless-ngx — built in SwiftUI, on top of The Composable Architecture.

This is a complete rewrite of Less Paper, and it has not been released yet — what is on the App Store today is still the old app. It supports paperless-ngx 3.0.0 and older versions.
A public beta is available on TestFlight: https://testflight.apple.com/join/3CM21m1n
If your server offers OpenID Connect sign-in, the app shows the same providers on its sign-in screen and runs the login through a system browser sheet. For that flow to complete, the OAuth client your paperless instance uses needs two things on the identity provider:
lesspaper://oidc-callback registered as a redirect URI — this is how the browser hands the login back to the appIf the browser sheet ends on an error from the provider about the redirect URI, the callback URL above is the thing that's missing.
Building requires Xcode 26.5; everything else is pinned with mise, which installs Tuist, SwiftLint, SwiftFormat and everything else at the exact versions CI uses.
mise install # tools + `brew bundle` via the postinstall hook
tuist install # resolve Swift package dependencies
tuist generate # generate LessPaper.xcworkspace
mise run docker:start # bring up paperless-ngx
mise run docker:seed # fill it with realistic fixture data
mise run docker:stop
mise run ci:test:unit # run the unit tests
mise run ci:test:ui # run the XCUITest journeys (slow)
mise run ci:lint # SwiftLint + SwiftFormat
mise run format # apply formatting
mise run snapshots:diff # visual diff of changed snapshots
mise run screenshots:frame # re-render the App Store screenshots
The project is generated by Tuist from Project.swift, and split into modules declared in Tuist/ProjectDescriptionHelpers/Module.swift:
ApiInterface holds the models and use-case protocols; ApiImplementation holds the concrete networking. Features depend only on the interface, which is what keeps them testable.DocumentsFeature, TagsFeature, CustomFieldsFeature, …), each a TCA reducer plus its SwiftUI views.ShareApp alone, which stands in for the share extension so XCUITest can drive it without going through another app's share sheet. The per-feature harness apps this list once described are gone: UI tests drive the real app now — see Testing.Components for shared UI, TestSupport / ApiTestSupport / UITestSupport for the test helpers, and MarketingKit, which renders the App Store screenshots from committed captures.Dependency injection runs through swift-dependencies, persistence through swift-sharing, and networking through Get.
Tests are written with Swift Testing and cover unit tests and snapshot tests, plus XCUITest journeys that drive the real app.
The API layer is tested against a live paperless-ngx container rather than mocks, so the tests catch real API drift.
UI tests live in AppUITests and drive the assembled app end to end — onboarding, server management, settings, the create/edit/delete lifecycle of each entity, custom fields, and document browsing and editing — rather than a harness app per feature. Each test creates its own paperless user, so what it makes is invisible to every other test and the lists it opens start empty. The journeys run serially and take several minutes; they are the slow part of the suite, so CI reserves them for main and for pull requests labelled UITests or TestFlight.
Conventions for this codebase — comment style, TCA patterns, the confirmation-popup rule and more — live in AGENTS.md. Please read it before opening a pull request. Releasing to the App Store is a maintainer task, documented in docs/releasing.md.
MIT © Johannes Plunien
95 commits
1 commits
Swift
97.1%
Python
1.3%
Shell
1.2%
Less Paper - iOS client for Paperless-ngx
6
stars
96
commits
Swift
primary language
Sep 6, 2026
updated
A native iOS client for paperless-ngx — built in SwiftUI, on top of The Composable Architecture.

This is a complete rewrite of Less Paper, and it has not been released yet — what is on the App Store today is still the old app. It supports paperless-ngx 3.0.0 and older versions.
A public beta is available on TestFlight: https://testflight.apple.com/join/3CM21m1n
If your server offers OpenID Connect sign-in, the app shows the same providers on its sign-in screen and runs the login through a system browser sheet. For that flow to complete, the OAuth client your paperless instance uses needs two things on the identity provider:
lesspaper://oidc-callback registered as a redirect URI — this is how the browser hands the login back to the appIf the browser sheet ends on an error from the provider about the redirect URI, the callback URL above is the thing that's missing.
Building requires Xcode 26.5; everything else is pinned with mise, which installs Tuist, SwiftLint, SwiftFormat and everything else at the exact versions CI uses.
mise install # tools + `brew bundle` via the postinstall hook
tuist install # resolve Swift package dependencies
tuist generate # generate LessPaper.xcworkspace
mise run docker:start # bring up paperless-ngx
mise run docker:seed # fill it with realistic fixture data
mise run docker:stop
mise run ci:test:unit # run the unit tests
mise run ci:test:ui # run the XCUITest journeys (slow)
mise run ci:lint # SwiftLint + SwiftFormat
mise run format # apply formatting
mise run snapshots:diff # visual diff of changed snapshots
mise run screenshots:frame # re-render the App Store screenshots
The project is generated by Tuist from Project.swift, and split into modules declared in Tuist/ProjectDescriptionHelpers/Module.swift:
ApiInterface holds the models and use-case protocols; ApiImplementation holds the concrete networking. Features depend only on the interface, which is what keeps them testable.DocumentsFeature, TagsFeature, CustomFieldsFeature, …), each a TCA reducer plus its SwiftUI views.ShareApp alone, which stands in for the share extension so XCUITest can drive it without going through another app's share sheet. The per-feature harness apps this list once described are gone: UI tests drive the real app now — see Testing.Components for shared UI, TestSupport / ApiTestSupport / UITestSupport for the test helpers, and MarketingKit, which renders the App Store screenshots from committed captures.Dependency injection runs through swift-dependencies, persistence through swift-sharing, and networking through Get.
Tests are written with Swift Testing and cover unit tests and snapshot tests, plus XCUITest journeys that drive the real app.
The API layer is tested against a live paperless-ngx container rather than mocks, so the tests catch real API drift.
UI tests live in AppUITests and drive the assembled app end to end — onboarding, server management, settings, the create/edit/delete lifecycle of each entity, custom fields, and document browsing and editing — rather than a harness app per feature. Each test creates its own paperless user, so what it makes is invisible to every other test and the lists it opens start empty. The journeys run serially and take several minutes; they are the slow part of the suite, so CI reserves them for main and for pull requests labelled UITests or TestFlight.
Conventions for this codebase — comment style, TCA patterns, the confirmation-popup rule and more — live in AGENTS.md. Please read it before opening a pull request. Releasing to the App Store is a maintainer task, documented in docs/releasing.md.
MIT © Johannes Plunien
95 commits
1 commits
Swift
97.1%
Python
1.3%
Shell
1.2%