crudy
    FeaturesUse CasesDocumentationPricingAboutContact
    Get started free
    Documentation
    • Introduction
    • Installation
    • Quickstart
    • CLI Reference
    • Overview
    • Core Packages
    • App Structure
    • Modules & Routes
    • Module Anatomy
    • Backend Module
    • Frontend Module
    • Quotas
    • Full Example
    • Overview
    • Docker
    • Environment Variables
    • Licensing
    Architecture

    App Structure

    Layout of an app folder under apps/<name>/.

    A scaffolded app is intentionally small. Almost every file is either configuration or a one-line re-export of a framework page. The only files that hold app-specific logic are backend/server.ts, frontend/app/providers.tsx, and anything you add under migrations/ and seeds/.

    Tree

    plaintext
    my-app/
      app.config.json
      license.lic              # issued by Crudy, gitignored
      license-public.pem       # issued by Crudy
      .env.example
      Makefile                 # per-app docker compose wrappers
      docker-compose.yml
      docker-compose.dev.yml
      backend/
        server.ts
        package.json
        Dockerfile
        Dockerfile.dev
        tsconfig.json
      frontend/
        package.json
        next.config.ts
        proxy.ts
        postcss.config.js
        tsconfig.json
        Dockerfile
        Dockerfile.dev
        app/
          layout.tsx
          page.tsx
          providers.tsx
          globals.css
          login/page.tsx
          [...slug]/page.tsx
      migrations/
      seeds/

    app.config.json

    The single source of app metadata read by both halves.

    json
    {
      "name": "my-app",
      "title": "My App",
      "audience": "my-app",
      "description": "My App",
      "fallbackRoute": "/",
      "licenseFile": "./license.lic",
      "licensePublicKeyFile": "./license-public.pem"
    }

    audience must match the audience declared in your license. If they differ, the backend exits at boot. Always set the audience here, never from the environment. Send this value to Crudy when you request a license at /pricing.

    backend/server.ts

    The only place modules are named on the backend.

    ts
    import { createCrudyServer } from '@crudy/backend';
    import appConfig from '../app.config.json' with { type: 'json' };
     
    await createCrudyServer({ modules: [], appConfig });

    Add a module by importing its backend half and listing it in the modules array:

    ts
    import { documentsBackend } from '@crudy-modules/documents/backend';
     
    await createCrudyServer({ modules: [documentsBackend], appConfig });

    frontend/app/providers.tsx

    The only place modules are named on the frontend.

    tsx
    "use client";
     
    import type { ReactNode } from "react";
    import { CrudyProviders } from "@crudy/frontend";
    import type { AppConfig } from "@crudy/frontend";
    import { documentsFrontend } from "@crudy-modules/documents/frontend";
    import rawConfig from "../../app.config.json";
     
    const appConfig = rawConfig as AppConfig;
    const MODULES = [documentsFrontend];
     
    export function AppProviders({ children }: { children: ReactNode }) {
        return (
            <CrudyProviders modules={MODULES} appConfig={appConfig}>
                {children}
            </CrudyProviders>
        );
    }

    layout.tsx imports AppProviders and renders it under <html><body>. It only owns metadata and viewport.

    frontend/app/page.tsx, login/page.tsx, [...slug]/page.tsx

    Each is a one-line re-export of a framework page:

    tsx
    "use client";
    export { HomePage as default } from '@crudy/frontend';

    [...slug]/page.tsx is the catch-all that resolves to a module-registered route by exact path. Module pages register through FrontendModule.routes, never by adding files under app/.

    frontend/app/globals.css

    A single line that imports the framework's compiled CSS:

    css
    @import "@crudy/frontend/globals.css";

    Modules that need their own globals add their own @import line here. Do not import Tailwind in your app's globals; each package owns its own.

    frontend/proxy.ts

    Configures the Next.js middleware that proxies API calls and gates routes.

    ts
    import { createMiddleware } from '@crudy/frontend';
    import rawConfig from '../app.config.json';
    import type { AppConfig } from '@crudy/frontend';
     
    export default createMiddleware(rawConfig as AppConfig);
    export const config = { matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'] };

    license.lic and license-public.pem

    The two license files Crudy sends you. Place them at the app root and the backend will pick them up via LICENSE_FILE and LICENSE_PUBLIC_KEY_FILE. See Licensing for the full lifecycle.

    migrations/

    Per-app SQL files applied after the core migrations. Use these for app-specific tables that no module owns.

    seeds/dev.sql

    Per-app dev fixtures. The backend re-applies them on a clean database. Do not use in production.

    PreviousCore PackagesNext Modules & Routes
    crudy

    Build internal tools your teams actually use. Powered by a framework built for developers.

    Product

    • Features
    • Use Cases
    • Pricing

    Company

    • About
    • Contact

    © 2026 Crudy. All rights reserved.

    crudy.fr