VibeAny Docs

Project structure

Learn where routes, business workflows, adapters, content, and configuration belong.

VibeAny uses Next.js App Router with explicit boundaries between presentation, application workflows, domain logic, and infrastructure. Knowing those boundaries makes customization faster and keeps provider-specific code from spreading through the application.

Top-level layout

src/
  app/              Next.js pages, layouts, route handlers, and global CSS
  proxy.ts          Locale handling, auth redirects, and API rate limits
  interfaces/       HTTP, CLI, MCP, cron, and webhook adapters
  features/         Presentation-facing UI and API wrappers
  application/      Use cases, ports, actor context, policies, and orchestration
  entities/         Pure domain models, types, and algorithms
  infrastructure/   Database and provider adapters implementing application ports
  shared/           Shared UI, providers, hooks, stores, types, and helpers
  lib/              Low-level integration and configuration modules
  i18n/             Locale messages, loaders, schemas, and validation scripts

content/blog/       Localized MDX blog content
drizzle/            Reviewed SQL migrations and Drizzle metadata
scripts/            Setup, preflight, release, and maintenance commands
tests/unit/         Fast Vitest tests
tests/integration/  Database-backed integration tests
tests/e2e/          Playwright browser tests

Routing

Application routes live under src/app. Locale-aware pages use the src/app/[locale] segment, so their public URLs begin with /en, /zh, or /es.

Route groups in parentheses organize files without adding a URL segment:

Source filePublic route
src/app/[locale]/(marketing)/page.tsx/en
src/app/[locale]/(marketing)/pricing/page.tsx/en/pricing
src/app/[locale]/(auth)/signup/page.tsx/en/signup
src/app/[locale]/(auth)/login/page.tsx/en/login
src/app/[locale]/dashboard/page.tsx/en/dashboard
src/app/api/(billing)/payments/webhook/route.ts/api/payments/webhook
src/app/api/auth/[...all]/route.ts/api/auth/*

The root src/app/page.tsx redirects / to the configured default locale. src/proxy.ts handles locale routing, protects /dashboard and /account, and applies API rate limits.

Keep route files thin. Parse transport input and return a transport response there, but put business decisions in application use cases.

Application boundaries

entities/

Use this layer for pure business rules that do not access the network, database, filesystem, or framework APIs. Credit allocation and subscription state types are examples.

application/

Use cases coordinate a user or system action. Ports describe the capabilities a use case needs without selecting Stripe, Creem, PostgreSQL, Resend, or another concrete provider.

infrastructure/

Adapters implement application ports. Database repositories, payment gateways, email delivery, storage, and model providers belong here. Provider SDK objects should not leak into pages or domain entities.

features/

Feature folders own presentation-facing components, hooks, schemas, and thin API wrappers. They may invoke application behavior, but should not become a second domain or persistence layer.

shared/

Reusable UI and framework helpers live here. The shadcn-compatible UI components are in src/shared/ui, and components.json maps the shadcn ui alias to that directory.

lib/

This directory contains low-level integration and configuration surfaces that are still used broadly, including authentication, database setup, SEO, and the product catalog. New business orchestration should still prefer application ports and use cases.

Common customization map

TaskPrimary location
Change product identity, domain, or support addressessrc/lib/config/brand.ts
Rewrite landing, SEO, and legal copysrc/i18n/locales/*/marketing.json and legal.json
Rearrange landing sectionssrc/features/marketing/ui/home-content.tsx
Change plans, credit packages, and provider IDssrc/lib/config/products.ts and environment variables
Change colors and theme tokenssrc/app/globals.css
Replace the logo and browser iconpublic/logo.svg and public/icon.svg
Add a localized marketing pagesrc/app/[locale]/(marketing)/<slug>/page.tsx
Add shared UIsrc/shared/ui
Change database tablessrc/lib/db/schema.ts, followed by a generated migration
Add a providerAn application port plus an infrastructure adapter and composition wiring

A typical request path

For a payment checkout, the public route validates HTTP input, a presentation wrapper invokes an application use case, and infrastructure selects the configured payment gateway. The provider webhook returns through the same adapter boundary before application code records provider-neutral billing state.

Next.js route
  -> feature or interface adapter
  -> application use case and port
  -> infrastructure provider adapter
  -> external provider or PostgreSQL

This separation is why the active payment provider can change without rewriting the checkout UI or the subscription domain model.

Before adding code

  1. Decide whether the change is presentation, orchestration, a pure domain rule, or an external side effect.
  2. Put it in the owning layer rather than the nearest existing file.
  3. Reuse an existing application port before importing a provider SDK elsewhere.
  4. Add focused tests at the same boundary.
  5. Run the relevant tests, then npm run typecheck:all and npm run build before release.

Continue with Environment configuration or Branding and internationalization.

On this page