You're reading docs for Nextly Alpha. APIs may change between releases.

Getting Started

Project Structure

Understand how a Nextly project is organized, where key files live, and what each directory does.

A Nextly project follows the standard Next.js App Router structure with a few additions: a nextly.config.ts at the root, admin routes under src/app/admin/, and API routes for the backend. This page explains where everything lives and what each part does.

Directory Overview

Here is the structure of a project scaffolded with create-nextly-app (Blank template, with src/ directory):

my-nextly-app/
├── src/
│   ├── app/
│   │   ├── admin/
│   │   │   ├── [[...params]]/
│   │   │   │   ├── page.tsx          # Admin panel UI (client component)
│   │   │   │   └── layout.tsx        # Admin layout — injects branding CSS
│   │   │   └── api/
│   │   │       └── [[...params]]/
│   │   │           └── route.ts      # Admin API catch-all handler
│   │   ├── api/
│   │   │   ├── health/
│   │   │   │   └── route.ts          # Health check endpoint
│   │   │   ├── media/
│   │   │   │   └── [[...path]]/
│   │   │   │       └── route.ts      # Media upload + serving
│   │   │   ├── media-folders/
│   │   │   │   └── route.ts          # Media folder management
│   │   │   └── [[...params]]/
│   │   │       └── route.ts          # REST API catch-all
│   │   ├── layout.tsx                # Root layout
│   │   ├── page.tsx                  # Home page
│   │   ├── globals.css               # Global styles
│   │   └── favicon.ico
│   └── types/
│       └── generated/
│           └── nextly-types.ts       # Auto-generated TypeScript types
├── public/
│   └── uploads/                      # Default local-disk media storage
├── nextly.config.ts                  # Nextly configuration
├── next.config.ts                    # Next.js configuration
├── eslint.config.mjs
├── postcss.config.mjs
├── tsconfig.json
├── package.json
├── .env                              # Environment variables (gitignored)
└── .env.example                      # Environment template

The Blog template adds a few more folders -- src/collections/, src/singles/, src/components/, src/access/, src/actions/, src/lib/, plus a (frontend) route group for the public-facing blog pages. See Templates → Blog for the blog-specific layout.

Key Files

nextly.config.ts

The central configuration file. This is where you define code-first collections, singles, plugins, storage adapters, email configuration, and admin branding. It lives at the project root.

nextly.config.ts
import { defineConfig } from "nextly/config";

export default defineConfig({
  collections: [/* your collections */],
  singles: [/* your singles */],
  plugins: [/* your plugins */],

  storage: [/* storage adapters */],
  email: { /* email provider config */ },

  admin: {
    branding: {
      logoText: "My App",
      colors: { primary: "#387c26" },
    },
  },

  typescript: {
    outputFile: "./src/types/generated/nextly-types.ts",
  },
});

See Configuration for the full reference.

next.config.ts

Standard Next.js configuration. The main Nextly-specific addition is serverExternalPackages, which prevents Next.js from bundling server-only dependencies like database drivers:

next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  serverExternalPackages: [
    "nextly",
    "@nextlyhq/adapter-drizzle",
    "@nextlyhq/adapter-postgres",
    "@nextlyhq/adapter-mysql",
    "@nextlyhq/adapter-sqlite",
    "drizzle-orm",
    "drizzle-kit",
    "pg",
    "mysql2",
    "better-sqlite3",
    "bcryptjs",
    "sharp",
    "esbuild",
  ],
};

export default nextConfig;

The Blank template ships with all dialect adapters listed; remove the ones you aren't using to keep the dev server tree clean.

.env

Environment variables for database connection and authentication. The CLI generates a complete .env with secure defaults; the essentials are:

VariableRequiredPurpose
DB_DIALECTYesDatabase type (postgresql, mysql, sqlite)
DATABASE_URLYes (PG/MySQL)Database connection string. SQLite falls back to file:./data/nextly.db
NEXTLY_SECRETYes (production)Secret for JWT signing and session encryption. Min 32 chars; the CLI auto-generates a base64 value
NEXT_PUBLIC_APP_URLYes (production)Public URL of your app, used by metadata and the admin

Storage env vars are only needed when you opt in to a cloud adapter -- the default is local disk under public/uploads/. See Environment Variables for the full list.

Key Directories

src/app/admin/

The admin panel lives here as a standard Next.js route. The catch-all [[...params]] pattern lets Nextly handle all admin panel routing internally.

  • page.tsx -- Renders the admin panel UI. This is a client component that imports RootLayout, QueryProvider, and ErrorBoundary from @nextlyhq/admin.
  • layout.tsx -- Reads admin.branding from nextly.config.ts and injects the generated CSS so logos and colors apply on every admin page.
  • api/[[...params]]/route.ts -- The admin API. Handles all CRUD operations for collections, singles, users, roles, permissions, and media.

src/app/api/

Public REST API routes. The catch-all [[...params]]/route.ts dispatches every endpoint Nextly ships -- collections, singles, auth, image sizes, email -- through one handler that reads your config. Health, media, and media-folders are split into their own routes for clarity. See REST API for every endpoint.

public/uploads/

Default media store when no storage adapter is configured in nextly.config.ts. Files uploaded through the admin's media library land here and are served directly by Next.js. To switch to S3, Vercel Blob, or Uploadthing, see Media & Storage.

src/types/generated/

Auto-generated TypeScript types for your content schema. The output path is configured in nextly.config.ts under typescript.outputFile. In development the types are regenerated automatically when you save nextly.config.ts; in production run:

pnpm nextly generate:types

Schema files (Visual Schema Builder)

When you create collections through the Visual Schema Builder, Nextly writes the generated TypeScript schema files alongside your project under the directory configured in nextly.config.ts -- by default ./src/db/schemas/. Those files are regular defineCollection() exports you can commit to version control. Code-first collections live in nextly.config.ts (or wherever you import them from); the two approaches coexist freely.

Code-First vs Visual Schema Builder: Where Content Is Defined

ApproachWhere collections are definedSchema location
Code-Firstnextly.config.ts (or files you import from it)Generated during pnpm nextly migrate (production) or auto-synced on save (dev)
Visual Schema BuilderAdmin panel at /admin/builder/collectionsTypeScript files written to disk under ./src/db/schemas/

Both approaches produce the same result: database tables, admin UI, REST endpoints, and Direct API access. You can mix them -- define some collections in config and create others through the Visual Schema Builder.

Next Steps