All projects

nvoicely

Full-stack invoice management for freelancers and small businesses. Create invoices, track clients and expenses, schedule recurring billing, send via email, and export to PDF.

View on GitHub

nvoicely project preview

Nvoicely

Full-stack invoice management web application for freelancers and small businesses.

What it does

  • Create, edit, and manage invoices with line items, taxes, and multi-currency support (IDR, USD, EUR, and more)
  • Maintain a client database and link invoices to clients
  • Track business expenses
  • Schedule recurring invoices (weekly, monthly, etc.)
  • Send invoices to clients via email
  • Export invoices to PDF
  • Dashboard with revenue and outstanding balance overview

Tech stack

  • Frontend: TanStack Start (SSR + file-based routing), React 19, Tailwind CSS v4, shadcn/ui, Radix primitives
  • Backend: Appwrite (auth, databases, storage, functions)
  • PDF generation: @react-pdf/renderer
  • Email: Appwrite Functions + Resend
  • Forms: React Hook Form + Zod
  • State: TanStack Query
  • Hosting: Cloudflare Workers

Getting started

pnpm install
cp .env.example .env  # fill in Appwrite credentials
pnpm run setup        # provision Appwrite databases
pnpm run dev

Scripts

CommandDescription
pnpm devStart the dev server
pnpm buildProduction build (Vite + Cloudflare worker)
pnpm previewRun the built worker locally (workerd)
pnpm typecheckType-check with tsc
pnpm deployBuild and deploy to Cloudflare Workers manually
pnpm setupProvision Appwrite databases
pnpm seedSeed sample data

Deployment

Hosted on Cloudflare Workers via the @cloudflare/vite-plugin (config in wrangler.jsonc). Deploys are automatic through Cloudflare Workers Builds — every push to master builds and deploys the Git integration; no manual step needed. pnpm deploy is available for an ad-hoc manual deploy.

Environment variables

Env vars split by when they are needed:

VariableWhenWhere (Cloudflare)
VITE_APPWRITE_ENDPOINTbuild-time (baked into client)Workers Build variables
VITE_APPWRITE_PROJECT_IDbuild-timeWorkers Build variables
APPWRITE_ENDPOINTruntimeWorker Variables / wrangler.jsonc
APPWRITE_PROJECT_IDruntimeWorker Variables / wrangler.jsonc
APPWRITE_DATABASE_IDruntimeWorker Variables / wrangler.jsonc
APPWRITE_API_KEYruntimeWorker Secret

The VITE_* variables must be set as Build variables (a different place from the runtime Variables/Secrets). If they are missing at build time the app throws a masked HTTPError 500 on load (the Appwrite client rejects an empty endpoint).

Releases

Versioning is automated with release-please. Push Conventional Commits (feat:, fix:, feat!:) to master and release-please keeps an open release PR with an updated CHANGELOG.md. Merging that PR bumps package.json, tags vX.Y.Z, and publishes a GitHub Release.