Repository navigation
Development Guide
Applies to the current
mainimplementation. Last source review: 2026-08-06.
This guide describes the repository's current npm-based workflow and the architectural boundaries expected of contributions.
- Node.js 24.15.0 or newer;
.nvmrcpins the reproducible local baseline. - npm 11.16.0, using the committed
package-lock.jsonandpackageManagerdeclaration. - Git.
- Optional for native download-engine work:
par2,unrar, and7zzonPATH. - Docker with the Compose plugin for production-image and container testing.
git clone https://github.com/TannerMidd/Nooklet.git
cd Nooklet
npm ci
cp .env.example .envPowerShell:
git clone https://github.com/TannerMidd/Nooklet.git
Set-Location Nooklet
npm ci
Copy-Item .env.example .envSet independent AUTH_SECRET, BOOTSTRAP_TOKEN, and SECRET_BOX_KEY values of at least 32 characters. Never commit .env, databases, local paths, queue payloads, or credentials.
Start the development server:
npm run devThe default development URL is http://localhost:42021. This command keeps
Next.js hot reload in the web process, watches and rebuilds the isolated worker
bundle under ignored .codex-tmp/, and runs storage checks in disposable probe
children. A slow media mount therefore cannot consume the web process's
filesystem thread pool during development.
| Command | Purpose |
|---|---|
npm run dev |
Start the hot-reloading web server, isolated worker, and disposable storage probes on port 42021 |
npm run typecheck |
Run TypeScript without emitting output |
npm run lint |
Run ESLint across the repository |
npm test |
Run Vitest in the Node environment |
npm run test:scripts |
Test migration/module validators plus storage-probe and worker-watchdog infrastructure |
npm run test:e2e |
Run the Chromium first-admin/login/axe smoke |
npm run audit:dependencies |
Reject high/critical production dependency advisories |
npm run docs:wiki:check |
Validate Wiki structure, internal links/anchors, and repository source targets |
npm run docs:dossier:check |
Validate the engineering dossier and generated configurator commands |
npm run docs:links:check |
Validate published README/docs/dossier source paths and reject retired external-downloader names |
npm run migrations:check |
Validate journal ordering, tags, timestamps, and SQL artifacts |
npm run boundaries:check |
Reject cross-module imports into repository/adapter internals |
npm run build |
Build and sanitize the standalone production bundle |
npm run start:web |
Start only the built Next.js web process; pair it with start:worker
|
npm run start:worker |
Start the built worker plus its disposable storage-probe coordinator |
npm run check |
Validate docs/source links, migrations, module boundaries, types, lint, infrastructure/application tests, and the production build |
npm run db:generate |
Generate a Drizzle migration after a schema change |
npm run db:backup |
Create and verify a SQLite backup using .env
|
npm run account:recover -- --email ... |
Recover a locked-out account locally |
Source: package.json.
src/app/ routes, layouts, server actions, and API boundaries
src/components/ shared and feature UI
src/config/ navigation and project-level presentation configuration
src/lib/ database, framework, security, and integration foundations
src/modules/ domain commands, queries, repositories, adapters, and workflows
drizzle/ generated SQL migrations and snapshots
docs/ ADRs, behavior requirements, architecture notes, and Wiki source
scripts/ backup, recovery, and standalone-build utilities
See Architecture for current module ownership.
- Keep route handlers and server actions thin: authenticate, parse, authorize, delegate, and shape a user-safe result.
- Put multi-step behavior in the owning domain workflow rather than a screen component.
- Do not call raw vendor adapters from UI code.
- Prefer typed, task-shaped commands and queries over generic setting or proxy endpoints.
- Keep credentials server-side, encrypted at rest, masked in summaries, and absent from audit payloads.
- Validate environment, action, route, adapter input, and adapter output boundaries.
- Preserve normalized persistence and add indexes for new query predicates.
- Keep the supported one-container topology in mind; do not introduce an external runtime dependency without an explicit architecture decision.
The decision basis is ADR-0001, but current implementation should be checked because some older examples in that ADR have drifted. See Architecture Decisions.
For a new or materially changed workflow:
- Define validated input and explicit output/error types.
- Keep orchestration separate from adapter and persistence details when the flow has multiple phases.
- Authorize at the server boundary and enforce ownership again in repository/workflow queries.
- Add a wiring or behavior test that exercises phase ordering and failure propagation.
- Persist user-visible failure state when work continues asynchronously.
- Add audit or notification behavior for security-sensitive and operationally important outcomes.
- Update the behavior matrix and relevant Wiki pages when user-observable behavior changes.
Follow the closest existing module pattern rather than creating empty template directories.
- Change
src/lib/database/schema.ts. - Generate one logical migration with
npm run db:generate. - Inspect generated SQL and Drizzle metadata, then run
npm run migrations:check. - Add repository/query tests that read and write the new shape.
- Consider upgrade and rollback behavior for existing SQLite files.
- Keep migration and consumer commits separately reviewable when practical.
Never edit an already-published migration to represent a new logical change.
Ask these questions for every boundary change:
- Can a user read or mutate another user's row?
- Can a URL reach loopback, private, link-local, metadata, or redirected targets?
- Can a supplied path escape an approved root through
.., a symlink, or platform-specific syntax? - Can an error, log, audit payload, or browser response reveal a secret or protected download URL?
- Is a high-risk operation rate-limited?
- Does a background failure remain visible and retry safely?
Use the existing helpers under src/lib/security rather than implementing one-off checks.
git status --short
git diff --check
npm run typecheck
npm run lint
npm test
npm run buildRun npm run boundaries:check after module import changes, npm run migrations:check after any schema/journal change, npm run audit:dependencies after dependency changes, and npm run test:e2e when bootstrap, authentication, protected navigation, or shared form semantics change.
Run npm run docs:wiki:check and npm run docs:links:check after Wiki or published source-link changes; run npm run docs:dossier:check as well when the engineering dossier or configurator changes.
Run the smallest relevant validation during iteration and the full proportional suite before handoff. Review the complete diff for secrets, generated noise, debug output, dead code, stale names, and unrelated changes. Use focused Conventional Commit subjects such as fix(downloads): ... or docs(wiki): ....
Implementation is not complete when operator behavior changes but the relevant documentation remains stale. Use Documentation Policy to identify the canonical page and source links to update.
Related: Testing and CI | Architecture | Security Model
Nooklet repository · Features · User guide · Engineering dossier · Issues · Private security advisory
Documentation last reviewed against main: August 19, 2026.
Nooklet
Start here
- Getting started
- Guided Docker setup
- Docker installation
- Native installation (advanced)
- First-time setup
Configure
Use Nooklet
- Discover and recommendations
- Library and requests
- YouTube monitoring
- Downloads and import
- Watch history
- Automation and notifications
Operate
- Health and diagnostics
- Backup, restore, upgrades
- Accounts and users
- Troubleshooting
- Multi-instance boundaries
Engineering