使い方
- インストールコマンドをコピーし、自分の環境へ導入する前にソースを確認します。
- 必要なツール、認証情報、対応環境を原文で確認します。
- 入力と成果物を指定し、出力を資料と照合します。
npx skills add https://github.com/bascikdev/bascik --skill bascik-migrate開始前の確認
- 導入にはモデル契約、API枠、ファイルへのアクセス許可は含まれません。
- スター数や導入数は活動の指標であり、独立した品質・安全性試験ではありません。
見出し、例、コード、表、リンク、参照画像を含む原文を表示しています。
Migrating to Bascik
Requires the bascik skill for component rules and the bascik-scripts skill for build-time data.
To have coding agents refactor a live site to production parity at every breakpoint and 100 in all five Lighthouse categories, install the opt-in bascik-refactor skill (npx skills add bascikdev/bascik --skill bascik-refactor) and read node <skills-dir>/bascik/scripts/read-doc.mjs /how-to/agent-migration.
Procedure
- Inventory. List every URL, shared layout region (
<head>tags, header, footer, nav), repeated widget, data source, and client behavior. Runnode <skills-dir>/bascik/scripts/list-components.mjsif Bascik components already exist. - Read the framework guide.
node <skills-dir>/bascik/scripts/read-doc.mjs /switch/from-<framework>(react,next,vue,svelte,astro,eleventy,hugo,wordpress). Read it before writing any code; it maps each framework feature to its Bascik equivalent. - Pages first. One
.htmlper URL insrc/pages/, each with its own<html>,<head>, and<body>. Parameterized URLs become dynamic route templates. - Extract components. Each page ends up as a list of tags, not a pasted block of the old site's HTML. Shared head becomes
<site-head />; header, footer, and nav become components; each section with a nameable job (hero, pricing, reviews, signup form) becomes a component; repeated widgets become one component with props and slots. Follow the old site's component boundaries where they are sound, but do not copy wrappers that only existed for the framework (providers, layout shells, one-element components) or props threaded through layers: use a slot instead. Usenew-component.mjs(in thebascikskill) for the folder layout, and thebascik-componentsskill for where to split.
Keep or improve the semantics. Carry over every semantic element the old site has (<nav>, <header>, <main>, <article>, <button>, <label>, heading levels), and never turn semantic markup into <div>s to make a component fit. Make each component's root the element for its job (a nav component's root is the <nav>, not a <div> around it), and replace framework div soup with the right element where it is safe: a clickable <div> becomes a <button type="button">, a list of links becomes a <ul>. Checklist: node <skills-dir>/bascik/scripts/read-doc.mjs /component-best-practices#use-htmls-elements.
- Keep TypeScript. A TypeScript source site stays TypeScript: component logic moves to a
.tscompanion or an inline<script type="text/typescript">and keeps its types (prop types become the@bascikcomment and the types of what the script reads), and data loaders become typed helpers insrc/lib/*.ts. A JavaScript site gets TypeScript for every new file unless the person says otherwise. Erasable syntax works with no setup; forenum, decorators, or npm packages in the browser, use esbuild (thescripts.typescriptsnippet in thebascikskill). Docs:/scoped-javascript#typescript-in-component-scripts,/configuration#scriptstypescript,/how-to/bundling-npm-packages. - Move styles. Delete framework scoped-style mechanisms and put the CSS in each component's companion
.css. Class names stay the same; Bascik scopes them. Global styles go tosrc/pages/css/styles.css. - Move behavior. Replace state and effects with a TypeScript script per component, targeting elements by
id. Prefer HTML and CSS solutions where they exist: a framework disclosure becomes<details>, a modal becomes<dialog>, a dropdown becomespopover. Attach click handlers to<button>and<a>elements, not to<div>s, and put state a screen reader needs in ARIA attributes (aria-expanded,aria-pressed). - Move data. Framework data loaders become
data-bascik-buildscripts that call typed helpers insrc/lib/. Escape every interpolated value. - Verify.
node <skills-dir>/bascik/scripts/verify.mjs --buildandnode <skills-dir>/bascik/scripts/audit-components.mjs(exit 0, or each kept warning explained), then compare old and new pages URL by URL.
Cross-framework mapping
| Concept | Bascik |
|---|---|
Component file (.jsx, .tsx, .vue, .svelte, .astro) | src/components/<name>/<name>.html with a hyphenated name (Card.vue becomes info-card), plus <name>.ts for its behavior |
.ts and .tsx logic, prop and state types | Typed <name>.ts companion or <script type="text/typescript">; shared types and helpers in src/lib/*.ts |
Scoped styles (<style scoped>, CSS Modules, Svelte styles) | Companion <name>.css, scoped automatically |
children, <slot />, {@render children()} | data-bascik-slot (no value), fallback inside |
| Named slots, render props, snippets | <div data-bascik-slot="x"> in the template and as the wrapper at the usage site |
Props (defineProps, $props(), props.x) | data-bascik-prop-x, text only |
| Prop bound to an attribute | data-bascik-attr-<attribute>="propName" |
| Object, array, or function props | Not possible: print one component per item from a build script, or embed JSON in <script type="application/json"> (escape < as \u003c) |
useState, ref, $state | Typed variables in the component script, applied to the DOM by a function |
Callback props, $emit, v-model | dispatchEvent(new CustomEvent('x', { bubbles: true, detail })), parent listens on its root |
v-if, {#if}, conditional JSX | Build time: a build script prints one branch. Runtime: toggle hidden |
.map(), v-for, {#each} | Build-time loop in a build script, or clone a <template> at runtime |
| File-system routing | One .html per URL in src/pages/ |
[slug], getStaticPaths, generateStaticParams, pagination | src/pages/blog/[slug].html (or [slug]/index.html for trailing slashes) with <script data-bascik-routes> |
getStaticProps, onMounted fetch, front matter | <script data-bascik-build> for shared data; fetch() in a component script for per-visitor data |
| Layouts | Pages keep <html>/<head>/<body>; layout pieces become components |
| Template includes with variables, filters, loops (Nunjucks, Liquid, Go templates) | TypeScript helpers in src/lib/ returning escaped HTML. Only static includes become components |
Content collections (getCollection, Eleventy collections) | A src/lib/posts.ts helper: fs read, gray-matter, zod, sort by parsed date |
API routes (app/api/x/route.ts) | src/api/x.ts exporting GET/POST; context.params is a plain object; needs bascik --server |
next/link, next/image, next/font | <a>, <img> with width/height, self-hosted @font-face plus <link rel="preload"> |
| RSS/Atom feeds | A pipeline.exec script with phase: 'post' writing to BASCIK_OUT_DIR |
| Image optimization, syntax highlighting | Not built in; add your own build step |
Gotchas that apply everywhere
- Escape every interpolated value in build scripts; JSX and Vue templates did it for you.
- Component tag names need a hyphen.
- Named-slot wrappers are removed, so wrap headings and links in a
<div data-bascik-slot="x">. - Elements created with `document.createElement` get no element-selector styles. Clone a
<template>in the component instead. - Production moves component scripts to the end of the document. Look up elements inside handlers or after
DOMContentLoaded; keep pre-paint scripts (theme) in<head>. - Re-sync form state on `pageshow` after Back/Forward or reload.
- `bascik --check` reports components printed only by build scripts as unused. That is expected.
- Add `"html.validate.scripts": false` to `.vscode/settings.json` (or run
bascik init, which merges it in). Otherwise VS Code joins a page's<script>blocks into one file and reports false errors such as "A module cannot have multiple default exports". - Do not generate page files into `src/pages/`. Use dynamic routes.
- Exclude data-reading build scripts from the cache (
scripts.cache.exclude) and watchcontent/(pipeline.watchPaths). - Tailwind: run it as a
preexec script withscoping.attributes.class: false; seeread-doc.mjs /libraries. - Start from the examples for layout, SEO tags, a blog, and interactive widgets:
add-example.mjs --listin thebascikskill.
Existing sitemap.xml and robots.txt
- Read both files.
- If they contain nothing Bascik would not generate (no hand-curated URLs, live
Disallowrules, external sitemap index pointer, or bot-specific directives), delete them. Bascik generates fresh ones at build time. Do not copy them intosrc/pages/and do not disablegenerate.sitemaporgenerate.robots. - If they contain custom directives, keep the authored file in
src/pages/, set the matchinggenerateflag tofalse, and add a config comment explaining why. - Exclude redirect-only pages from the generated sitemap with
<meta name="bascik-sitemap" content="exclude">.
Copying old files while disabling generation looks correct but freezes the sitemap at the old URL list forever.
For Astro, Eleventy, and Hugo, read the live guide with read-doc.mjs /switch/from-astro (or from-eleventy, from-hugo).
