A modern invoice management application built with SvelteKit 5, featuring Better Auth authentication, Drizzle ORM with Neon database, and CUID2 for resilient ID generation.
Clone and install dependencies:
git clone <repository-url>
cd dollar-holler
bun install
Set up environment variables: Create a .env file in the root directory:
DATABASE_URL="postgresql://username:password@hostname:port/database"
PUBLIC_BASE_URL="http://localhost:5173"
BETTER_AUTH_SECRET="your-strong-secret"
Set up the database:
# Generate migrations
bun run db:generate
# Run migrations
bun run db:migrate
# Seed the database with sample data
bun run db:seed
Start the development server:
bun run dev
Optional: Preview production build
bun run build && bun run preview
bun run dev - Start development serverbun run build - Build for productionbun run preview - Preview production buildbun run check - Run Svelte checkbun run check:watch - Run Svelte check in watch modebun run db:generate - Generate Drizzle migrationsbun run db:migrate - Run database migrationsbun run db:seed - Seed database with sample databun run db:studio - Open Drizzle Studiobun run db:push - Push schema directly to the databasebun run format - Format source with Prettierbun run lint - Run Prettier check and ESLintsrc/
├── lib/
│ ├── auth.ts # Better Auth configuration
│ ├── auth-client.ts # Client-side auth utilities
│ ├── db/
│ │ ├── index.ts # Database connection (Neon HTTP)
│ │ ├── schema.ts # Drizzle schema definitions
│ │ ├── seed.ts # Database seeding script
│ │ └── migrate.ts # Migration utilities
│ ├── elysia/
│ │ ├── index.ts # ElysiaJS app with mounted routes
│ │ ├── auth-plugin.ts # Better Auth integration plugin
│ │ └── routes/ # API route modules (clients, invoices, settings)
│ ├── components/ # Reusable UI components
│ │ ├── ui/ # Bits UI components
│ │ └── ... # Custom components
│ ├── attachments/ # Svelte 5 @attach directives
│ ├── stores/ # Svelte stores (client, invoice, settings)
│ ├── utils/ # Helper functions
│ └── validators.ts # ArkType validation schemas
├── routes/ # SvelteKit routes
└── app.html # HTML template
The application uses the following main tables:
user - Better Auth user accountssession - User sessionsaccount - OAuth accountsverification - Email verification tokensclients - Client informationinvoices - Invoice recordsline_items - Invoice line itemssettings - User settingsAll tables use CUID2 for primary keys and include proper foreign key relationships with cascade deletes.
The application uses Drizzle's relations to simplify nested queries (e.g., db.query.invoices.findMany({ with: { client: true, lineItems: true } })) and avoid manual joins in API routes.
The application is configured for Vercel deployment with the Vercel adapter. Ensure your DATABASE_URL and BETTER_AUTH_SECRET environment variables are set in your Vercel project settings.
rolldown-vite by aliasing vite in package.json (drop-in replacement). If issues arise with third-party plugins, see Vite's rolldown guide for withFilter and environment APIs.eslint.config.mjs and uses Svelte 5 rules and Prettier integration. Use bun run format before bun run lint.@attach directive for modern component patterns and the Spring class for smooth animations.MIT