Engram is a local-first spatial workspace for capturing thoughts, tasks, links, images, and files on a canvas. The canvas is the source of truth; Timeline and Priorities are projections over the same item records.
The current project is a high-fidelity v1 prototype built in a Bun/Turborepo
monorepo. It persists Engram data in browser localStorage through an adapter
boundary that is intended to be replaced by a sync-backed adapter later.
Note: the generated workspace/package scope is still
alphonse/@alphonse. The product and app feature are Engram.
- Spatial canvas for notes, tasks, links, images, and file cards.
- Drag cards around an infinite-feeling React Flow canvas.
- Create visible curved links between cards.
- Quick capture for thoughts, tasks, links, and attachments.
- Task priority and due-date capture, including lightweight natural-language
parsing such as
tomorrow 3pmand!p1. - Timeline and Priorities views computed from task items.
- Search and jump-to-item behavior.
- Local persistence with validation and corrupt-payload backup.
- Runtime/package manager: Bun
- Monorepo: Turborepo
- Frontend: Next.js, React, Tailwind CSS
- Canvas: React Flow (
@xyflow/react) - UI primitives: shadcn-style components in
packages/ui - Backend: Hono and tRPC
- Auth: Better Auth
- Database: PostgreSQL with Drizzle ORM for server/auth tables
- Desktop shell: Tauri
- Validation: Zod
- Formatting/linting: Oxlint and Oxfmt
engram/
+-- apps/
| +-- web/ # Next.js app and Tauri desktop shell
| +-- server/ # Hono server, auth routes, tRPC endpoint
+-- packages/
| +-- api/ # tRPC router/context package
| +-- auth/ # Better Auth configuration
| +-- db/ # Drizzle config and database schema
| +-- env/ # Shared environment validation
| +-- config/ # Shared TypeScript config
| +-- ui/ # Shared UI primitives and global styles
+-- docs/
+-- plans/ # Product and architecture plans
+-- superpowers/ # Prototype planning notesThe Engram feature itself lives in:
apps/web/src/features/engram/
+-- engram-core.ts # Pure domain mutations and invariants
+-- projections.ts # Timeline, priorities, recent items, search
+-- persistence.ts # Persistence adapter seam and localStorage adapter
+-- store.tsx # React store wrapper around the domain core
+-- ui-store.tsx # UI-only state
+-- types.ts # Space, Item, ItemLink, CanvasViewState
+-- components/ # Canvas, sidebar, capture, search, task viewsInstall dependencies:
bun installCreate apps/server/.env for the server and database packages:
DATABASE_URL=postgres://user:password@localhost:5432/engram
BETTER_AUTH_SECRET=replace-with-at-least-32-characters
BETTER_AUTH_URL=http://localhost:3030
CORS_ORIGIN=http://localhost:3031
NODE_ENV=developmentCreate apps/web/.env.local for the web app:
NEXT_PUBLIC_SERVER_URL=http://localhost:3030Push the Drizzle schema when using the auth/server flow:
bun run db:pushRun the full development stack:
bun run devOpen the web app at http://localhost:3031. The API server runs at http://localhost:3030.
To run only one side:
bun run dev:web
bun run dev:server/redirects to/canvas/canvasis the main Engram workspace/timelineshows task items grouped by time/prioritiesshows task items grouped by priority/loginand/dashboardare scaffolded auth/dashboard routes
bun run dev # Start all apps through Turborepo
bun run dev:web # Start only the Next.js app on port 3031
bun run dev:server # Start only the Hono server on port 3030
bun run build # Build all apps/packages
bun run check-types # Typecheck all apps/packages
bun run check # Run Oxlint and Oxfmt
bun run db:push # Push Drizzle schema
bun run db:generate # Generate Drizzle migrations
bun run db:migrate # Run Drizzle migrations
bun run db:studio # Open Drizzle StudioDesktop development:
cd apps/web
bun run desktop:dev
bun run desktop:buildDesktop builds use the Tauri app under apps/web/src-tauri. Packaging static
web assets may require additional Next.js export/static-build configuration.
Engram keeps domain behavior separate from React and storage:
engram-core.tsowns mutations and invariants.projections.tsderives read-only views from stored records.persistence.tsdefines the storage adapter boundary.store.tsxwires React state, domain mutations, and debounced persistence.- Canvas cards are React Flow nodes, and item links are React Flow edges.
The stored records are intentionally shaped like future synced rows:
SpaceItemItemLinkCanvasViewState
Tasks are Item records, not separate task records. Timeline and Priorities
should remain projections instead of persisted views.
Implemented for v1:
- Single-user local prototype.
- Local browser persistence.
- Canvas-first data model.
- Search, quick capture, task projections, and link deletion.
Out of scope for v1:
- Real multi-device sync.
- Multi-user collaboration.
- External calendar sync.
- AI features.
- Full file storage pipeline.
- Rich document editing.
See docs/plans/2026-06-06-engram-design.md for the detailed product and architecture plan.