Skip to main content
StormyCMS

Getting Started with StormyCMS

This guide takes you from nothing to a running Stormy site with its own admin editor.

Prerequisites

  • Node.js 20.9 or newer
  • pnpm 10 (corepack enable or npm i -g pnpm)
  • A Stormy CMS site with client credentials (Client ID and Client Secret)
  • Optional: S3-compatible object storage for media uploads from the admin editor

Step 0: Create a Site and Get Credentials

  1. Sign in at account.stormycms.com with GitHub or Google (every account includes one free site with one seat)
  2. Go to Dashboard → Sites → New Site and create your site
  3. Open your site's Keys page to copy your Client ID
  4. Generate your Client Secret from the same page — it's revealed once, so store it somewhere safe

If you ever need to rotate credentials, the Keys page can reset both the client ID and the client secret at any time.

Step 1: Scaffold a Project

The stormy init command creates a new project from the official Next.js boilerplate:

Terminal window
npx @stormycms/cli init
# or, with the CLI installed globally:
stormy init

You'll be prompted for a project name and target directory, then for your environment values (optional). The CLI then initializes a git repository with an initial commit and installs dependencies.

Non-interactive usage:

Terminal window
stormy init --name my-project --target ./my-project --skip-env
stormy init --name my-project --skip-install
FlagDescription
-n, --name <name>Project name (lowercase kebab-case, e.g. my-stormy-site)
-t, --target <path>Target directory (defaults to ./{project name})
--skip-envSkip environment prompts and use example values
--skip-installCreate the project without installing dependencies

Step 2: What You Get

The generated project is a pnpm + Turborepo monorepo:

my-stormy-site/
├── apps/
│ ├── site/ # Public CMS-rendered site (localhost:3000)
│ └── admin/ # Your own admin editor (localhost:4000)
└── packages/
├── components/ # Shared React components + CMS export map
└── types/ # Shared ambient type declarations

The key idea: packages/components is imported by both apps. The admin editor renders the same components as the public site, so previews are always accurate — and there is no separate schema to maintain in an external portal.

Step 3: Configure Environment Variables

If you used --skip-env, copy and fill in the env files:

Terminal window
cp apps/admin/.env.example apps/admin/.env
cp apps/site/.env.example apps/site/.env

apps/site/.env

VariableDescription
NEXT_PUBLIC_SITE_URLThe public site URL (e.g. http://localhost:3000)
STORMY_CMS_CLIENT_IDYour site's client ID (sent as x-client-id)
STORMY_CMS_CLIENT_SECRETYour site's client secret (sent as x-client-secret)

apps/admin/.env additionally needs:

VariableDescription
STORMY_CMS_REDIRECT_URLOAuth callback, e.g. http://localhost:4000/api/auth/stormy
NEXT_PUBLIC_SITE_URLThe admin URL used for auth redirects (e.g. http://localhost:4000)
NEXT_PUBLIC_PREVIEW_SITE_URLThe public site URL for previews (e.g. http://localhost:3000)
S3_ENDPOINT, S3_BUCKET, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_REGIONS3-compatible storage for media uploads

Important: never commit .env files or expose STORMY_CMS_CLIENT_SECRET in client-side code.

Step 4: Run It

Terminal window
pnpm dev

Sign in to the admin with GitHub or Google. You can now create layouts and pages visually, edit component fields, and manage media — all rendered with your own components.

Step 5: Make Your First API Request (Optional)

Everything the admin does goes through the same GraphQL API you can call directly:

const response = await fetch('https://api.stormycms.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-client-id': process.env.STORMY_CMS_CLIENT_ID,
'x-client-secret': process.env.STORMY_CMS_CLIENT_SECRET,
},
body: JSON.stringify({
query: `
query GetPages($limit: Int, $offset: Int) {
pages(limit: $limit, offset: $offset) {
id
slug
metadata { title description keywords }
}
}
`,
variables: { limit: 10, offset: 0 },
}),
});
const result = await response.json();
console.log(result.data.pages);

Most applications won't need raw fetch calls — @stormycms/core provides a typed client (StormyCMSClient) that handles headers, auth, and parsing for you.

What's Next?

Security Best Practices

  • Never expose your client secret in client-side code — keep API calls in server components, route handlers, or server actions
  • Use environment variables for all credentials
  • Reset your client secret (via the API or your account portal) if you suspect it's been compromised
  • Use HTTPS for all API requests in production
  • Use a restricted S3 bucket credential for media uploads in production

Last updated: 7/10/26, 3:17 AM

StormyCMSThe headless CMS where you own the management panel
Community
StormyCMS