Skip to content
Meeko
Type to search the guides and the API reference. Open it from any page with / or Ctrl K; move with the arrow keys and open a result with Enter.
Get started

Contents

On this page

buildProject

Builds the project like meeko build, without the preliminary check, and returns the adapter and output folder; for build scripts and tools.

advanced API Since 1.0.0 @meekojs/meeko/build Source code
ts
import { buildProject } from "@meekojs/meeko/build";

buildProject is meeko build as a function: it compiles the client with Vite, the adapter's server and prerendered pages, writes sitemap.xml and robots.txt if enabled and returns { adapter, output }. The adapter comes from options.adapter, server.adapter in meeko.config.ts or, by default, node.

Unlike the command, it does not check the project first (neither components nor TypeScript) and does not read .env. Since 1.7, in a clean project (after meeko clean or in a fresh CI checkout, without prior meeko check or meeko dev) it first generates declarations and .meeko/'s tsconfig.*.json files, like meeko check; if they already exist, it does not rewrite them. Through 1.6, it failed with Tsconfig not found …/.meeko/tsconfig.app.json. Use it for custom build scripts, building multiple adapters in one process and integration tests.

Usage#

ts
// scripts/build.ts
import { buildProject } from "@meekojs/meeko/build";

const { adapter, output } = await buildProject(process.cwd());
console.log(`build ${adapter} in ${output}`);

Type#

ts
function buildProject(
  projectRoot: string,
  options?: BuildProjectOptions,
): Promise<BuildProjectResult>

BuildProjectOptions

ts
interface BuildProjectOptions {
	readonly adapter?: MeekoAdapterName
}

BuildProjectResult

ts
interface BuildProjectResult {
	readonly adapter: MeekoAdapterName
	readonly output: string
}

Parameters#

Parameter Type Default Description
projectRoot path required Project folder.
options.adapter "node" | "bun" | "deno" | "cloudflare" | "static" server.adapter, or "node" Overrides the configured adapter.

Return value#

A promise of { adapter, output }: the adapter used and the absolute path of .meeko/output/<adaptador>/. The folder contains the same output as meeko build (see its page).

Rejects with the error from the failing step: Adaptador desconocido: …; usa node, cloudflare, deno, bun o static, the error for a project retaining server/session.ts, for a sitemap without a public origin, for an application unsupported by the static adapter, Dynamic prerender route … requires prerenderEntries, or Vite's error.

Examples#

Two adapters in one script#

ts
import { buildProject } from "@meekojs/meeko/build";

for (const adapter of ["node", "cloudflare"] as const) {
  const result = await buildProject(process.cwd(), { adapter });
  console.log(result.adapter, result.output);
}

Each build writes its own folder; the second does not delete the first.

Check and build, like the CLI#

ts
import { execFileSync } from "node:child_process";
import { buildProject } from "@meekojs/meeko/build";

execFileSync("npx", ["meeko", "check", "."], { stdio: "inherit", shell: process.platform === "win32" });
await buildProject(process.cwd());

buildProject does not run TypeScript: without the preliminary check, a type error reaches production if the code compiles with Vite.

An integration test#

ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { buildProject } from "@meekojs/meeko/build";

test("the Node build serves the home page", async () => {
  const { output } = await buildProject("tests/fixtures/app", { adapter: "node" });
  const { createNodeApp } = await import(`${output}/index.mjs`);
  const app = await createNodeApp();
  assert.equal((await app.fetch(new Request("http://localhost/"))).status, 200);
  await app.close();
});

Common mistakes#

Expect the meeko build check#

Incorrectts
await buildProject(process.cwd()); // the project has a TS2322 error in server/api

Vite strips types without checking them: the build completes and the error reaches production. meeko build runs meeko check first; buildProject does not.

Correctts
await checkProjectWithCli();
await buildProject(process.cwd());

An adapter that does not exist#

Incorrectts
await buildProject(process.cwd(), { adapter: "vercel" as never });

Rejects with Adaptador desconocido: vercel; usa node, cloudflare, deno, bun o static, before compiling anything.

Correctts
import { buildProject } from "@meekojs/meeko/build";

await buildProject(process.cwd(), { adapter: "node" });

Environment variables the build needs from .env#

Incorrectts
// .env: MEEKO_PUBLIC_ORIGIN=https://example.com, and sitemap: true without site
await buildProject(process.cwd());

buildProject does not read .env (the CLI does): sitemap necesita la URL pública del sitio: declara site en meeko.config.ts (site: "https://example.com") o define MEEKO_PUBLIC_ORIGIN al construir.

Correctts
process.env.MEEKO_PUBLIC_ORIGIN ??= "https://example.com";
await buildProject(process.cwd());

Notes#

  • Node only. Requires vite installed in the project; building and prerendering run in Node even with another adapter.
  • Modules. Executes meeko.config.ts and module setup functions, and calls their build:before, routes:resolved and build:done hooks.
  • Since 1.7. The Node build and other server adapters include contentSecurityPolicy, headers and a new buildId in the manifest, and prerendering evaluates sitemapEntries.
  • Concurrency. Two simultaneous builds of the same project share .meeko/build/ and .meeko/output/client/: run them sequentially, as in the example.
  • Performance. At least two Vite passes (client and server), plus one per standalone adapter and another for the Node server if sitemap is enabled.

Was this page helpful?

Add a comment

It is sent when you choose “Yes” or “No”. Only the page, your answer and the comment are stored: no cookies and no personal data.

0 of 2000 characters

Edit on GitHub: docs/en/reference/advanced/buildproject.md