Open source · for freelancers & small agencies

One true statusfor every client project.

Stop relaying updates through WhatsApp, email threads, and spreadsheets that all disagree. Ledger centralizes the work and shows the right slice to the right person, automatically.

See how it works
app.ledger.dev/northwind

Projects · 3 active

Northwind — Brand refresh
12 open
Alder Studio — Site rebuild
4 overdue
Moss & Co — Q3 campaign
7 open

Alder Studio — Site rebuild

Export final logo files
SK
Client review — homepage copy
ZE
Fix mobile nav breakpoint
ZE

Before → after

17 unread WhatsApp messages“quick question” thread, 43 repliesStatus_FINAL_v3.xlsxwrong Drive folder shared“any update?” — sent Tuesday
ProjectStatusUpdated
Halden RetailOn track2h ago
Voss StudioNeeds input1d ago
Marsh & Co.DeliveredJust now

Inside Ledger

Built for the work, not the demo

Projects & tasks

One board, not five spreadsheets

Kanban or list, every task carries a status, a priority, a due date, and an assignee — one who's actually assigned to that project, checked server-side, not just hidden in the UI.

To do

Draft homepage copy
Source hero photography

In progress

Build client portal auth

Done

Kickoff call notes
Brand color palette

Client portal

Clients see their project. Nothing else.

A client invited into the portal gets exactly their own project — progress, files, milestones, a place to comment. Not the org's other clients. Not internal-only tasks. The boundary is enforced in the database, not painted over in the UI.

portal.ledger.dev/alder-studio
Alder Studio — Site rebuildyour project
Northwind — Brand refresh
Moss & Co — Q3 campaign

Activity timeline

The truth, generated, not typed

A file upload, a finished task, a new comment — every real action writes one event. That single stream powers the timeline you see and the email notification that lands seconds later. One source, never two systems drifting apart.

Sana marked “Export final logo files” done

2m ago

Client uploaded brand_assets_v2.zip

1h ago

Zine commented on the homepage draft

3h ago

What Ledger actually does

Everything client work needs. Nothing it doesn't.

Tasks, kanban and list

Every task carries a status, priority, due date, and an assignee — one who's actually assigned to that project, enforced server-side, not just by the UI.

Files, scoped per project

Uploads live in Cloudinary but are only ever visible to the people on that specific project. Not the org. Not other clients. That project.

An activity timeline that isn't manual

Uploads, comments, task completions — the timeline is generated from real actions as they happen, not typed up by someone after the fact.

Notifications from the same source

Email notifications fire off that same activity stream. One event, one source of truth, two outputs — never two systems drifting apart.

A dashboard with real signal

Health indicators computed from overdue tasks and last activity per project. Not a decorative counter that's always green.

Search that's backend-driven

Indexed search and filtering across tasks and projects — built for when a small agency's client list stops fitting on one screen.

Access that's actually enforced

Owner, team member, client — each one is scoped in the database, not just hidden in the UI. Try the wrong URL and you get denied, not an empty page.

Open source · MIT

Built in the open, on a stack you already trust

No hidden backend, no black-box auth. Two repositories — NestJS API, Next.js frontend — a Prisma schema you can read end to end, and a request path with nothing skipped in between.

Next.jsTypeScriptReactTailwind CSSNestJSPrismaPostgreSQLDockerClerkCloudinaryResendSentry
Next.js — App RouterVercel
API layerREST, JSON
NestJSGuards · DI · modules
Prismatype-safe queries
PostgreSQLNeon

Security

Tenant isolation isn't a feature. It's the floor.

Clerk handles identity

Sessions, JWTs, password resets, email verification — one battle-tested provider, not a hand-rolled auth system to audit.

Roles live on the membership

Access isn't read off the JWT — it's checked against the Membership row for that specific organization, every request.

Denied means denied

Cross-tenant access returns 403 or 404, never an empty array. An empty list quietly confirms something exists; Ledger doesn't leak that.

GET /organizations/org_2/members
Authorization: Bearer <org_1_member_token>
403 Forbidden
{ "message": "Not a member of this organization" }

Access, enforced

Three people, three views, one project

01

Owner

Every client, every project, every teammate — the whole org.

02

Team member

Only the projects they're assigned to. Nothing else in the org.

03

Client

Their own project, sandboxed. No other clients, no internal tasks.

Roadmap

Shipped in the open, one slice at a time

Every version is demoable end to end — never a half-wired feature.

V0

Foundation

Repos, full schema, Docker, health check, CI.

Shipped
V1

Auth & organization core

Clerk auth, org creation, role guards, cross-org isolation tested.

Shipped
V2

Clients & projects

Client CRUD, project scoping by assignment.

Shipped
V3

Tasks & milestones

Kanban, list view, status filters.

Shipped
V4

Files & comments

Cloudinary uploads and comment threads, scoped per project.

In progress
V5

Activity & notifications

Timeline and email off one event stream.

In progress
V6

Dashboard & search

Real health indicators, indexed search.

Planned
V7

Client portal

Token invite, sandboxed client-facing UI.

In progress
V8

Production polish

Dark mode, Sentry, Playwright, deploy.

Planned

Pricing

Start free. Talk to us when you're ready to grow.

Solo is free, no card required. Team and Agency are sized to how your studio actually works.

Solo

For freelancers running one or two clients.

Freeforever
  • 1 client
  • 3 active projects
  • Kanban & list views
  • File uploads
Most popular

Team

For small agencies with a team to coordinate.

Let's talk pricing
  • Unlimited clients & projects
  • Team members & role-based access
  • Activity timeline
  • Email notifications
Contact sales

Agency

For agencies ready to bring clients into the loop.

Let's talk pricing
  • Everything in Team
  • Client portal invites
  • Project health dashboard
  • Priority support
Contact sales

FAQ

Questions worth answering straight

Freelancers and small agencies running client work through scattered WhatsApp threads, email, and spreadsheets. If status lives in five places that disagree with each other, that's the problem Ledger centralizes.

Yes — both repositories, frontend and backend, are public under an MIT license. No paid-only core, no source-available license games.

A client starts as a contact record — name, email, company — with no login. Portal access is a separate, deliberate step: you send an invite, they accept it, and they land in a view scoped to exactly their own project. Nothing else in the org.

At the database level. Every project belongs to one organization and one client; a team member's project list is filtered to what they're assigned; access checks run against the Membership row, not just hidden in the UI. Cross-tenant requests are denied, not filtered client-side.

Next.js and NestJS, TypeScript throughout, PostgreSQL via Prisma, Clerk for auth, Cloudinary for files, Resend for email. Full list is in the developer section above.

Yes. It's two ordinary repos with a docker-compose for local Postgres — no proprietary infrastructure required to run it yourself.

Run client work like it's written down once.