{"product_id":"nextjs-saas-dashboard-starter","title":"Next.js SaaS Dashboard Starter - TypeScript, Tailwind \u0026 SQLite","description":"\u003cp\u003eA complete starting point for a subscription web app, written from scratch: a \u003cstrong\u003eNext.js 16\u003c\/strong\u003e (App Router, React Server Components, server actions) project in strict \u003cstrong\u003eTypeScript\u003c\/strong\u003e with \u003cstrong\u003eTailwind CSS 4\u003c\/strong\u003e design tokens and a built-in \u003cstrong\u003eSQLite\u003c\/strong\u003e database. It runs locally with \u003cstrong\u003enpm install\u003c\/strong\u003e and \u003cstrong\u003enpm run dev\u003c\/strong\u003e: no Docker, no database server, no external service, no API keys.\u003c\/p\u003e\u003ch2\u003eWhat is inside\u003c\/h2\u003e\u003cul\u003e\n\u003cli\u003eA designed public landing page with hero, feature grid, pricing with a monthly\/yearly switch, FAQ and footer\u003c\/li\u003e\n\u003cli\u003eSign-up and sign-in with scrypt password hashing, signed httpOnly session cookies stored as hashes in the database, constant-time comparison, and rate limiting on sign-in (5 attempts per email in 15 minutes) and on sign-up. Per-IP limits (30 sign-in attempts per 15 minutes, 10 sign-ups per hour) apply only when you set TRUST_PROXY=true behind one trusted reverse proxy that appends the client address to X-Forwarded-For; without it forwarded headers are ignored and all callers share one much larger bucket, so the per-email limit is the main protection\u003c\/li\u003e\n\u003cli\u003eSigned-in dashboard with a collapsible icon rail, workspace switcher, and light and dark themes (warm paper and graphite, one teal accent, system fonts, no web fonts)\u003c\/li\u003e\n\u003cli\u003eOverview page with monthly recurring revenue, growth against last month, active customers, net new customers, churn and average revenue per customer, plus hand-drawn SVG charts (area, grouped bars, donut, sparkline) with a screen-reader data table behind the area and bar charts and no chart library\u003c\/li\u003e\n\u003cli\u003eCustomers table with search, status tabs, plan filter, sortable columns and pagination, plus a customer page with revenue history and create, edit and delete\u003c\/li\u003e\n\u003cli\u003eProjects with plan-based limits, archive and restore, and edit and delete\u003c\/li\u003e\n\u003cli\u003eMultiple workspaces per account, with team members, invitation links (no email is sent; you copy the link), seat limits per plan and removal of members\u003c\/li\u003e\n\u003cli\u003eOwner, admin and member roles checked on the server for every action and for the restricted pages, not only hidden in the menu\u003c\/li\u003e\n\u003cli\u003eBilling against a simulated payment provider with test card numbers: immediate upgrades with proration, downgrades scheduled for the end of the period, cancel and resume, failed-payment handling with retry after the card is replaced, and an invoice list\u003c\/li\u003e\n\u003cli\u003eAudit log with filters for sign-ins, projects, customers, team, billing and workspace events\u003c\/li\u003e\n\u003cli\u003eSettings for profile, password change (signs out other sessions), workspace rename, leaving and deleting a workspace\u003c\/li\u003e\n\u003cli\u003eSmall hand-written SQLite data layer on the Node.js built-in node:sqlite module with versioned migrations (no native add-ons), Zod validation for every form, and a clock you can freeze for tests and demos\u003c\/li\u003e\n\u003cli\u003eSeed command that builds a demo workspace (fictional company, 3 demo users, 40 customers, 12 months of revenue, projects, invoices, an open invitation and an audit trail) and can be run again safely: the data is generated relative to the day you run it, running it again on the same day gives the same content, and the ids of workspaces, customers, projects and invoices stay the same (audit log, revenue rows and the invitation are rebuilt, and anything you added inside the two demo workspaces is removed). Set APP_FIXED_NOW (for example 2026-10-26T15:30:00Z) to reproduce the screenshots exactly\u003c\/li\u003e\n\u003cli\u003e88 automated Vitest tests covering the data layer, authentication, rate limiting, roles, billing and proration, the seed, validators and every server action, including hostile-input checks, plus a smoke script that requests every route as a signed-out visitor and as each demo role against a running server, with hostile query strings, unusual HTTP methods and bad ids\u003c\/li\u003e\n\u003c\/ul\u003e\u003ch2\u003eDemo accounts\u003c\/h2\u003e\u003cp\u003eAfter \u003cstrong\u003enpm run seed\u003c\/strong\u003e three fictional accounts exist in the Fernhill Studio workspace: maya.okafor@example.com (owner), daniel.reyes@example.com (admin) and priya.nair@example.com (member). The seed command prints the shared demo password, and also prints a demo invitation link you can open to try joining a workspace.\u003c\/p\u003e\u003ch2\u003eRequirements\u003c\/h2\u003e\u003cul\u003e\n\u003cli\u003eNode.js 22.18 or newer (the project uses the built-in node:sqlite module and runs TypeScript scripts directly) and npm. It was tested on Node.js 24.18 on Windows 11 only; Node.js 22.18 is the documented minimum and was not tested here\u003c\/li\u003e\n\u003cli\u003eWorks offline after npm install. The database file is created in a local .data folder on first run\u003c\/li\u003e\n\u003cli\u003enpm may print a notice that the install script of unrs-resolver was not run; linting works without it\u003c\/li\u003e\n\u003c\/ul\u003e\u003ch2\u003eHow to start\u003c\/h2\u003e\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003enpm install\u003c\/strong\u003e\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003enpm run seed\u003c\/strong\u003e (optional demo data)\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003enpm run dev\u003c\/strong\u003e and open http:\/\/localhost:3000\u003c\/li\u003e\n\u003cli\u003eFor a production build: \u003cstrong\u003enpm run build\u003c\/strong\u003e then \u003cstrong\u003enpm start\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eChecks: \u003cstrong\u003enpm run typecheck\u003c\/strong\u003e, \u003cstrong\u003enpm run lint\u003c\/strong\u003e, \u003cstrong\u003enpm test\u003c\/strong\u003e, and \u003cstrong\u003enpm run smoke\u003c\/strong\u003e while a server is running\u003c\/li\u003e\n\u003c\/ul\u003e\u003ch2\u003eDesign\u003c\/h2\u003e\u003cp\u003eA calm ledger look: warm off-white and graphite, a single teal accent, soft 1px borders instead of shadows, tabular numerals in tables, and sentence-case labels. Dark mode uses warm charcoal rather than blue-black. The layout adapts down to phone width with a slide-in menu that moves focus into the menu, keeps it there, closes on Escape and returns focus to the Menu button. Icons are drawn inline as SVG.\u003c\/p\u003e\u003ch2\u003eNot included\u003c\/h2\u003e\u003cul\u003e\n\u003cli\u003eNo real payment provider: billing is a simulation and nothing is ever charged. Swap in a provider SDK in one module when you are ready\u003c\/li\u003e\n\u003cli\u003eNo email sending, email verification, password reset, social sign-in or two-factor authentication\u003c\/li\u003e\n\u003cli\u003eNo ownership transfer, file uploads, translations or API for third parties\u003c\/li\u003e\n\u003cli\u003eNo HTTPS, reverse proxy or deployment configuration. SQLite is a single local file, so plan for a single server\u003c\/li\u003e\n\u003cli\u003eNo documentation files, Docker files or CI configuration\u003c\/li\u003e\n\u003c\/ul\u003e\u003cp\u003eDownload: one .zip with the source code only (Next.js app, components, data layer, migrations, seed and smoke scripts, tests and the configuration files needed to run them). Personal and Commercial licenses are explained on the store's license page.\u003c\/p\u003e","brand":"Snippet Crate","offers":[{"title":"Personal","offer_id":52045124468982,"sku":"SPF-NSD-PER","price":29.0,"currency_code":"USD","in_stock":true},{"title":"Commercial","offer_id":52045124501750,"sku":"SPF-NSD-COM","price":79.0,"currency_code":"USD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0831\/7776\/7158\/files\/nextjs-saas-dashboard-starter-cover.png?v=1793020864","url":"https:\/\/snippetcrate.com\/products\/nextjs-saas-dashboard-starter","provider":"Snippet Crate","version":"1.0","type":"link"}