Docs/Getting Started

Integrate Veap with Next.js

Veap is a collection of application packages, not a replacement for Next.js. Let Next.js own route discovery and rendering, and use Veap services from server-only modules, Route…

2 min read

Veap is a collection of application packages, not a replacement for Next.js. Let Next.js own route discovery and rendering, and use Veap services from server-only modules, Route Handlers, and Server Actions.

Define a server composition root#

ts
// src/server/veap.ts
import "server-only";
import { Application } from "@veap/kernel";
import { DatabaseServiceProvider } from "@veap/database";
import { MailServiceProvider } from "@veap/mail";
import { AuthServiceProvider } from "@veap/auth";

export const veap = Application.configure()
  .use(DatabaseServiceProvider)
  .use(MailServiceProvider)
  .use((container) => new AuthServiceProvider(container, { autoMigrate: false }))
  .create();

let bootPromise: Promise<void> | undefined;
export function ensureVeapBooted() {
  bootPromise ??= veap.bootstrap().catch((error) => {
    bootPromise = undefined;
    throw error;
  });
  return bootPromise;
}

Call services from server code#

ts
// app/api/health/route.ts
import { NextResponse } from "next/server";
import { ensureVeapBooted } from "@/server/veap";

export async function GET() {
  await ensureVeapBooted();
  return NextResponse.json({ status: "ok" });
}

This endpoint verifies application bootstrap only. It does not prove that a database query or a mail transport is healthy; add dependency-specific checks if your deployment needs them.

Use a Server Action#

ts
// app/actions.ts
"use server";

import { signIn } from "@veap/auth";
import { ensureVeapBooted } from "@/server/veap";

export async function loginAction(input: { email: string; password: string }) {
  await ensureVeapBooted();
  return signIn(input);
}

Validate user-controlled input at the boundary and follow the actual LoginInput declaration for the installed version. A client component should call this action; it should not import the database connection or service provider.

Avoid accidental client imports#

  • Keep composition roots and privileged service access in server-only modules.
  • Use @veap/intl/client and @veap/auth/client only inside Client Components.
  • Use @veap/intl/server and @veap/auth/server only in server modules.
  • Do not pass secrets, database instances, mailer objects, or raw session tokens to client components.
  • Do not assume @veap/kernel as a whole is browser-safe; evaluate each subpath and dependency.

Bootstrap considerations#

The kernel guards repeated bootstrap calls through a global promise and returns early in browser contexts and during the Next.js production build phase. The runtime is therefore designed to be initialized lazily from server execution paths. Verify behavior in your deployment mode, particularly if you use multiple worker processes, serverless functions, or custom runtimes.

veap
Preparing0%