HTML components. Zero runtime.
Bascik is a build tool for HTML components with automatically scoped CSS and JavaScript. You write vanilla HTML, CSS, and JavaScript. Bascik scopes and assembles reusable component files into plain static HTML pages at build time, with no framework runtime, no Shadow DOM, and no virtual DOM. The code that ships is the code you wrote.
Documentation: bascik.dev
Package: @bascik/bascik
npm organization: @bascik
npm create bascik my-siteThe CLI scaffolds a starter site and starts the dev server with live reload. See the Getting Started guide for manual setup in an existing project.
Building with an AI assistant? Install the Bascik agent skills so GitHub Copilot, Claude Code, Cursor, or Codex knows the component and scoping rules:
npx skills add bascikdev/bascik --skill bascik bascik-components bascik-images bascik-compatibility bascik-scripts bascik-seo bascik-config bascik-testing bascik-migrateRun without --skill in a terminal to choose skills interactively. A non-interactive run without --skill installs every skill, including the opt-in bascik-refactor (a workflow for refactoring a live site, which most projects do not need); name --skill bascik-refactor when you want it.
A component is an HTML file named after its tag. Its <style> and <script> are scoped to it at build time, so class names and DOM queries never collide with other components.
<!-- src/components/site-nav.html -->
<style>
.nav {
display: flex;
gap: 1rem;
}
</style>
<nav class="nav" data-testid="site-nav">
<a href="/">Home</a>
<a href="/about">About</a>
</nav>Use the tag in any page or component. There is no import, export, or registration step.
<!-- src/pages/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Home</title>
</head>
<body>
<site-nav />
</body>
</html>- Components and Slots
- Scoped CSS without Shadow DOM and Scoped JavaScript
- Build Scripts, Dynamic Routes, and Deployment
- Bascik vs React, Vue, Svelte, and Astro
This repository holds Bascik and everything around it. Each folder is a Yarn workspace unless noted.
| Folder | What it is | README |
|---|---|---|
pkg/ |
@bascik/bascik: the compiler, CLI, dev server, and production server |
pkg/README.md |
create/ |
create-bascik: the project scaffolder behind npm create bascik |
create/README.md |
lsp/ |
@bascik/language-server: diagnostics, completion, hover, and the --check linter for any LSP editor |
lsp/README.md |
extensions/vscode-bascik/ |
The VS Code extension, a thin client of the language server | extensions/vscode-bascik/README.md |
adapters/cloudflare/ |
@bascik/adapter-cloudflare: builds server scripts and API routes into a Cloudflare Worker |
adapters/cloudflare/README.md |
adapters/netlify/ |
@bascik/adapter-netlify: builds server scripts and API routes into Netlify Functions |
adapters/netlify/README.md |
docs/ |
The bascik.dev site, built with Bascik | docs/README.md |
examples/ |
Example components and a starter site to copy into a project (not a workspace) | examples/README.md |
skills/ |
Public agent skills for coding assistants, installed with npx skills add bascikdev/bascik (not a workspace) |
skills/README.md |
skills-tests/ |
Tests and fixtures for skills/, kept apart because skills/ ships to users |
skills-tests/README.md |
Develop on Node 26, the current LTS (.nvmrc pins it; Node 24 works too). The published packages support Node 24.21 and newer, and CI runs every suite on Node 26 and checks the floor in its own job. The repo uses Yarn 4 workspaces (yarn@4.18.0, through Corepack), so one install at the root wires everything up:
corepack enable
yarn install
yarn pkg:build # build the compiler first; the docs and tests use pkg/dist
yarn docs:dev # the docs site at http://localhost:8080, a good place to try a changenode_modules/@bascik/bascik is a symlink to pkg/, so the docs and other workspaces use your local build with no pack or reinstall step.
Root scripts are prefixed by workspace (pkg:, create:, lsp:, ext:, adapter:cf:, docs:, skills:), and the :all scripts run every workspace:
yarn pkg:unit # one workspace's unit tests (pkg:test watches)
yarn typecheck:all # TypeScript in every workspace
yarn check:all # formatting (Prettier), spelling (codespell), web standards (webhint)
yarn unit:all # unit tests in every workspace
yarn integration:all # tests that start real processes, servers, and browsers
yarn e2e:all # Playwright E2E: the four pkg server lanes, the docs, and the Cloudflare and Netlify adapters
yarn test:all # typecheck, checks, unit, integration, and E2E, plus a Lighthouse audit of the docs
yarn coverage:all # regenerate every coverage file in the table belowCI runs on every branch push, in gated stages, each starting only when the one before passes: static checks (typecheck, formatting, spelling, web standards, Jelly, Semgrep), unit tests, integration tests, then E2E. A fifth stage uploads a preview of bascik.dev and the Cloudflare adapter demo from every branch other than main, listing the two URLs in the run summary and in a comment on the branch's pull request, if it has one. A push to main (a merged pull request, already tested on its branch) skips the tests and only deploys both sites to production. Pull requests from forks are tested but never deployed; DEPLOYMENT.md is the runbook. Packages are released by pushing a tag, as described in RELEASING.md.
Before opening a pull request, run the checks for what you touched (at least the workspace's unit tests and yarn typecheck:all, plus yarn check:format). Add a bullet under [Unreleased] in CHANGELOG.md for every user-visible change in any package; CONTRIBUTING.md lists the house rules. Agent and contributor guidance lives in .github/copilot-instructions.md, which CLAUDE.md also loads.
| Workspace | Suite | Lines | Functions | Branches | Source |
|---|---|---|---|---|---|
@bascik/bascik (pkg/) |
Unit | 93.5% | 92.0% | 86.7% | JSON |
@bascik/bascik (pkg/) |
E2E build steps | 69.4% | 60.7% | 69.4% | JSON |
create-bascik (create/) |
Unit | 98.6% | 98.9% | 93.9% | JSON |
@bascik/language-server (lsp/) |
Unit | 92.9% | 92.5% | 85.9% | JSON |
bascik-vscode (extensions/vscode-bascik/) |
Unit | 46.2% | 46.7% | 60.0% | JSON |
@bascik/adapter-cloudflare (adapters/cloudflare/) |
Unit | 97.9% | 93.7% | 89.0% | JSON |
bascik-docs (docs/) |
Unit and integration | 63.2% | 68.3% | 69.4% | JSON |
bascik-skills-tests (skills-tests/) |
Unit | 57.3% | 57.9% | 56.4% | JSON |
Measured on November 1, 2026. Unit numbers come from each workspace's Vitest unit tests; pkg counts its unit project only, never its integration tests. The @bascik/bascik E2E row is measured separately, while the CLI builds the E2E fixture site and runs the dev and production servers, so it covers entry points and worker threads that unit tests cannot reach. skills-tests measures the skills' scripts in skills/. The extension's number is low because most of its code calls the VS Code API and runs only in the yarn ext:e2e suite, which is not measured; the diagnostics it shows are tested in lsp/. The docs number includes the docs' integration tests. Run yarn coverage:all to regenerate the JSON files; the Testing Internals page explains each suite and shows lines, statements, functions, and branches for all eight coverage files.