StoryLark
← All guides

Deploy your own site on Cloudflare

The supported Cloudflare deployment is a thin publisher project created from npm. It pins the StoryLark engine, Worker, and pipeline as dependencies and owns only your brand, presentation, deployment settings, workflows, and content. Cloning the engine is not part of this path.

Prerequisites

Create the publisher project

For one guided flow from an empty folder to a deployment:

npm create storylark my-site -- --deploy

To review and brand the project before provisioning anything:

npm create storylark my-site
cd my-site
npm run doctor
npm run setup

The create command runs npm install, writes a package lock, pins compatible versions of storylark-core, storylark-worker, and storylark-pipeline, and records non-secret provenance in .storylark/project.json. --no-install is an advanced escape hatch and cannot be combined with --deploy.

A cloned engine workspace is not an installed publisher site. If you intentionally clone the engine to develop or fork StoryLark, run npm install at its root before using any workspace command.

Brand the generated site

The generated project separates three contracts:

brands/<id>/brand.json                identity
brands/<id>/theme.css                 visual tokens
presentation/<id>/presentation.json  layout and vocabulary
deployment/<id>/deployment.json      origins and narration settings

Edit the brand and presentation before or after the first deployment. Runtime theme packages and brand edits are stored separately from engine versions, so an engine update does not overwrite them. See Build your own theme and Build your own presentation.

Run the setup wizard

npm run setup asks for the brand id, app URL, optional content URL, sender identity, and app name. It writes the gitignored platforms/cloudflare/install.env, verifies the values and Wrangler session, and asks before creating resources.

The installer creates or configures:

Keep the setup link and recovery codes in a password manager. Do not commit install.env, tokens, account identifiers, database identifiers, or secrets.

Same-origin content is the default

Leave CONTENT_ORIGIN empty for the simplest deployment. The Worker serves /manifest.json and /books/* from the R2 binding, so no second domain or DNS setup is required.

Set a separate content origin only when you intentionally attach an R2 custom domain. Audio and large content then bypass the Worker while R2 continues to provide zero-egress delivery.

Existing Cloudflare resources

The installer can adopt explicitly named existing Worker, D1, and R2 resources. Resource names are deployment details; they do not rename your brand. Run npm run doctor first and review the plan before confirmation. Adoption must not replace content, theme, presentation, or identity merely to match a default name.

Verify before publishing

Run the read-only diagnostics locally:

npm run doctor
npm run doctor -- --json

After deployment, verify the live origin, Admin sign-in, engine and Worker versions, update preflight, and content manifest. Follow Deployment safety before changing an existing production library.

Publish a story or book

The generated project uses content/ as its default Markdown source:

npm run publish

A single type: story file publishes a standalone story. A type: book declaration plus ordered type: chapter files publishes a multi-chapter book; both shapes can coexist. The bundled narrator is the free default on a local publisher machine. Use --no-audio only when you intentionally want text-only content.

See Authoring stories and books, Publishing stories and books, and the Content pipeline.

Operate the deployment

Open /admin for:

A GitHub Actions workflow that reads a repository and publishes through the content API does not create an Admin repo connection. Use Connect a repo if you want StoryLark to store and operate that connection. See the Admin guide.

Manual and advanced reference

The generated project includes platforms/cloudflare/install.mjs and an example install.env for scripted verification, deployment, update, repair, and explicit self-update opt-out. The exhaustive bindings, variables, secrets, and route behavior live in the engine deployment reference.

Cloudflare free limits are real limits, not an unlimited-hosting promise. App assets and API requests traverse the Worker so runtime engine updates can be selected; published content can use the R2 custom domain. Review the current architecture and budget notes before estimating production traffic.


Found a gap? StoryLark is open source — improve these docs on GitHub.