A quiet, local-first notebook for handwriting, sketches, maths, and PDFs.
Folio is a native Android notebook built with Kotlin and Jetpack Compose. Write with a stylus or finger, keep pages organized, and take your notebooks with you in .folio backups.
- Pressure-sensitive handwriting, drawing tools, and undo/redo
- Writing follow that measures your lines from the ink, holds still for corrections, and offers one-tap or automatic line return, plus a pinned peek view (hold to glance, tap to keep open)
- Typed notes, photos, and PDF annotation
- Long responses: pinned questions, plans, linked drafts and marked copies, side-by-side comparison, and feedback actions
- Ruled, dotted, grid, maths, and infinite-canvas pages
- Graph tool: centred or corner axes, optional grid, ticks, unit numbers and x/y labels
- Page bookmarks, search, and notebook organization
- Dedicated study timer: standalone or notebook-linked sessions, reflections, history, and Focal sync
- Reference view: a read-only PDF pane with contents, text search, page jump, zoom/fit and link following
- Export pages as PDF or PNG; save compact
.foliobackups with undo history, or use incremental automatic library backups (details) - Make it yours: your own accent colour, app text size, toolbar layout, quick ink colours, saved tool presets and notebook covers
- Core notebook works offline; Android 8.0 and newer
Download the latest APK from GitHub Releases.
Experimental builds are available from the Folio server. In Settings → Account & updates, enable Experimental builds to check that server; leave it off for stable GitHub releases. Server setup and publishing are documented in docs/release-server.md.
Requires JDK 17 and Android SDK 36.
./gradlew :app:assembleDebugFor repeated local builds, keep app/build and the Gradle caches: avoid clean
unless diagnosing a build problem. On Windows, use
.\build.ps1 -Tasks ':app:assembleDebug' for the same build without lint.
CI builds and publishes signed R8 releases on pushes to main or manual dispatch.
Run local build and lint checks with:
./gradlew :app:assembleDebug :app:lintDebugOn the configured VPS, run bash ./build.sh to make a signed experimental build,
then answer y to publish it. Each run gets a new version code even without a new
commit (commitCount × 10000 + localBuildNumber) and a name such as 2.1.7-exp.2.
Stable Gradle/CI builds use commitCount × 10000; the next stable commit therefore
supersedes the preceding experimental builds.
Version numbers are supplied lazily to the APK outputs. Focal connection settings
are generated separately from version metadata, so changing a commit or
experimental build number can reuse Kotlin/Java compilation in both debug and
release builds. Gradle's configuration and build caches remain enabled. To inspect
local task timings, add --profile to either build command; reports are written to
build/reports/profile/.
