Built For / Developers

The app framework that feels like code.

Define your schema in TypeScript. Query with a type-safe API. No black boxes, no vendor lock-in. Nextly lives inside your Next.js app.

A real collection definition. Fields, hooks, and access control in one TypeScript file.

import {
  defineCollection,
  text,
  richText,
  relationship,
  select,
} from "@revnixhq/nextly/config";

export const Posts = defineCollection({
  slug: "posts",
  fields: {
    title: text({ required: true }),
    body: richText(),
    author: relationship({
      to: "users",
      hasMany: false,
    }),
    status: select({
      options: ["draft", "published", "archived"],
      defaultValue: "draft",
    }),
  },
  hooks: {
    beforeChange: async ({ data, req }) => {
      // Mutate data before saving
      return data;
    },
    afterChange: async ({ doc, req }) => {
      // Trigger webhooks, revalidate cache, etc.
    },
  },
  access: {
    read: () => true,
    create: ({ req }) => req.user?.role === "editor",
    update: ({ req }) => !!req.user,
    delete: ({ req }) => req.user?.role === "admin",
  },
});

Stop fighting your tools.

Most content frameworks are designed to be sold to enterprises, not used by engineers. You end up fighting configuration, working around type safety, and maintaining a separate backend you didn't ask for.

Pain Point

Vendor lock-in

Hosted platforms own your data and your workflow. Migrating away costs months and rewrites.

Pain Point

Fighting the framework

Complex plugin APIs, undocumented internals, and runtime config that breaks TypeScript.

Pain Point

Poor TypeScript support

Auto-generated types that drift from reality. Runtime errors your compiler should have caught.

Pain Point

Separate backend to maintain

A standalone service just for content. Extra deployments, extra infra, extra ops overhead.

How Nextly helps developers.

Nextly runs inside your Next.js app, no separate service. Your schema is TypeScript. Your data lives in your own database.

TypeScript-Native Schema

defineCollection() is plain TypeScript. Types are structural, not generated as an afterthought. Your editor knows your schema before you run a single command.

Direct Database Access via Drizzle

Query your Postgres, MySQL, or SQLite directly with full type safety. Drizzle ORM under the hood, no abstraction hiding your data.

Schema Lives in Git

Collections are files. Migrations run as code. Branch, review, and deploy content structure the same way you ship features.

Lifecycle Hooks

beforeChange, afterChange, beforeRead. Intercept any operation to run custom logic, send webhooks, or transform data.

Access Control in Code

Declare access rules per collection, per field, per operation. Row-level security for tenant isolation. No GUI config to drift from your actual policies.

Self-Hosted, MIT Licensed

Run on any server, any cloud, or your local machine. The source is public. No Nextly cloud required.

Start building with Nextly

Free, open source, and yours to own. No sign-up required.

>_npx create-nextly-app@latest