Getting Started

Bascik runs on Node.js 24.21 or newer; Node.js 26, the current LTS, is recommended.

Quick Start

Create a new site with Bascik:

sh
npm create bascik@rc my-site -y

During the release candidate period, @rc selects the current release candidate.

That scaffolds the project, installs dependencies, and starts the dev server in one shot.

Open http://localhost:8080 in your browser to see your live site.

Edit a page or a component and save. The browser updates on its own, with no manual refresh:

An editor above a browser showing the starter site. A heading is edited and saved and the browser updates. A component's border color is edited and saved and every card updates

Create Bascik Command

sh
npm create bascik@rc my-site

Pass a different name to use it as both the directory name and the site title. The name is a new folder under the current one, such as my-site or sites/my-site: ., .., an absolute path and spaces are refused. If the folder already has a file the starter would replace, such as package.json or src/pages/index.html, nothing is written; to add Bascik to an existing project, see Manual Setup.

If you omit -y, the CLI steps through the setup prompts interactively.

npm create bascik@rc scaffolds a complete starter site: pages, components with unit tests, Playwright E2E browser tests, global CSS, vite.config.ts, .vscode/extensions.json recommending the official Bascik extension, .vscode/settings.json that turns off a VS Code check which gives false errors on Bascik pages, and a .gitignore with Vitest, npm run lint (bascik --check, with the @bascik/language-server linter installed), E2E testing, and code coverage pre-configured.

Its component scripts are TypeScript (<script type="text/typescript">), and every component root and interactive part carries a data-testid for tests. Run npm create bascik@rc -- --help to list every option.

It does not create bascik.config.ts because the starter uses Bascik's built-in defaults. A fresh project passes npm run lint; until you set the site's production URL, bascik --check warns that BASCIK_SITE_URL is not set and npm run build fails, because the sitemap and robots.txt need it. Set it where the site is built (see Environment files and the site URL), or turn off generate.sitemap and generate.robots. npm run e2e works before that: while neither BASCIK_SITE_URL nor .env sets a URL, its Playwright config gives the test build http://localhost:8080, the server it runs. Once you set one, the e2e build uses it, so the dist/ it leaves behind keeps your real sitemap.

For coding assistants, it writes an AGENTS.md brief with the project's commands and house rules, and a CLAUDE.md that imports it for Claude Code. It then asks whether to install the Bascik agent skills (yes by default, and with -y); pass --no-skills to skip them. See Project Brief for what the brief says.

To start a site that deploys to Cloudflare Workers, pass --template cloudflare. You get the same starter plus the Cloudflare adapter and Wrangler as dev dependencies, a build script that emits the Workers bundle, preview and deploy scripts, and a demo page with a server script and an API route that run in the Worker. --template netlify is the same for Netlify: the Netlify adapter, a netlify.toml, and the demo page and API route running in a Netlify Function. Without --template, the interactive prompts ask the same questions.

sh
npm create bascik@rc my-site -- --template cloudflare

The -- matters: npm keeps flags placed before it for itself and does not pass them on, so --template has to follow a --. -y works on either side of it because create-bascik also reads npm's own yes setting, so npm create bascik@rc my-site -y -- --template cloudflare scaffolds, installs, and starts the dev server without a single prompt. --no-skills and --no-install work on either side too, but --no-dev has to follow the --: npm treats it as one of its own settings and does not pass it on.

Manual Setup

To add Bascik to an existing project:

sh
npm install @bascik/bascik@rc

Run bascik init to create the starter directory structure, or add "dev": "bascik" and "build": "bascik --build" to your package.json scripts.

bascik --build also writes sitemap.xml and robots.txt, so it needs your site's URL and exits with an error until you set one: put BASCIK_SITE_URL=https://example.com in a .env file, set it in the environment, or pass --site-url. If the site needs no sitemap or robots.txt, set generate.sitemap: false and generate.robots: false instead. See Environment files and the site URL. The dev server does not need it.

bascik init also adds the AGENTS.md and CLAUDE.md project brief, appending to files you already have, and asks whether to install the agent skills. bascik init -y installs them without asking, and bascik init --no-skills skips them.

Editor Setup

bascik init also sets up VS Code: it adds a .vscode/settings.json with the setting below and recommends the Bascik extension in .vscode/extensions.json. It adds to files you already have and keeps what is in them. If you set up the project by hand, add this to .vscode/settings.json:

json
{
  "html.validate.scripts": false
}

VS Code's built-in HTML checker joins every classic <script> (one without type="module") in a file into one JavaScript file, so a page with two Bascik scripts that each export default shows the false error "A module cannot have multiple default exports." Bascik runs each script on its own. The setting turns off only VS Code's check of code inside <script> tags in .html files. The Bascik extension offers to add the setting to a Bascik workspace the first time it starts there, and changes nothing unless you click. See Several Scripts in One File for what the setting changes.

Third-party linters such as Webhint are optional. Neither npm create bascik@rc nor bascik init installs them or creates or changes their config files. If you use one, Editor Linters Read Source has copyable settings for warnings about head tags and prop-filled attributes that Bascik adds at build time.

html
<!-- src/components/site-nav.html -->
<style>
  .nav {
    display: flex;
    gap: 1rem;
  }
</style>
<nav class="nav">
  <a href="/">Home</a>
  <a href="/about">About</a>
</nav>
html
<!-- src/pages/index.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Home</title>
  </head>
  <body>
    <site-nav></site-nav>
    <main>
      <h1>Hello world</h1>
    </main>
  </body>
</html>

At build time, Bascik replaces <site-nav> with its component markup and scopes the class names its CSS uses into dist/index.html. The <nav> you wrote is the <nav> that ships, and the lang attribute and <main> landmark tell browsers and screen readers what the page is: see Component Best Practices for the elements to pick.

html
<!-- dist/index.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Home</title>

    <style>
      .bascik__site-nav__nav {
        display: flex;
        gap: 1rem;
      }
    </style>
  </head>
  <body>
    <!-- src/components/site-nav.html -->

    <nav class="bascik__site-nav__nav">
      <a href="/">Home</a>
      <a href="/about">About</a>
    </nav>

    <main>
      <h1>Hello world</h1>
    </main>
  </body>
</html>

See Working Components

The Example Components are tested components to read and learn from, from a site header to a contact form.

Your First Component

  1. 1

    Create the component file

    The file name becomes the tag name.

    html src/components/site-nav.html
    <!-- src/components/site-nav.html -->
    <style>
      .nav {
        display: flex;
        gap: 1rem;
      }
    </style>
    <nav class="nav">
      <a href="/">Home</a>
      <a href="/about">About</a>
    </nav>
  2. 2

    Reference it in a page

    No imports or registration. Just use the tag.

    html src/pages/index.html
    <!-- src/pages/index.html -->
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <title>Home</title>
      </head>
      <body>
        <site-nav></site-nav>
        <main>
          <h1>Hello world</h1>
        </main>
      </body>
    </html>
  3. 3

    Start the dev server

    sh
    npm run dev

    The server runs on http://localhost:8080 and live-reloads on every change.

  4. 4

    Build for production

    sh
    npm run build

    Output is written to the dist/ directory. Deploy it anywhere that serves static files.

Learn How Components Work

Discover how Bascik resolves custom tags, passes props, scopes CSS and JS, and handles slots with zero runtime footprint.

Explore Components →