Bascik vs Frameworks

Bascik is not a framework. It is a build tool that resolves components at compile time and then disappears. Understanding how that differs from popular lightweight frameworks helps you pick the right tool, and shows how they can work together.

What Bascik Does

Bascik solves one problem: component reuse at build time. Write a navigation bar once, use it on every page, and get clean HTML out. That is the entire scope.

Everything else, interactivity, server communication, reactive state, is your decision. You can ship zero JavaScript, or you can add as much as the project needs. Bascik does not have an opinion.

The custom component tags in a Bascik project are the ones you create. If you create site-nav.html, you can write <site-nav>. Bascik does not add a catalog of framework components with their own behavior or API.

Bascik does use a small set of build instructions such as data-bascik-slot, data-bascik-prop-*, and data-bascik-build. They use HTML's standard data-* extension mechanism to keep Bascik source valid HTML. Bascik consumes them during the build; they are not runtime directives that require browser JavaScript to interpret.

HTMX and Alpine.js

HTMX (~14 KB) and Alpine.js (~16 KB) both take an attribute-based approach to adding behavior to HTML. HTMX focuses on server-driven partial updates: you add attributes like hx-get, hx-post, hx-target, and hx-swap, and HTMX intercepts events, fires requests to your server, and swaps portions of the page with the response. Alpine focuses on client-side interactivity: x-data defines state, and directives like x-bind, x-show, and @click wire that state to the DOM.

Both are compatible with Bascik. Bascik resolves components at build time and produces vanilla HTML; HTMX and Alpine run in the browser on whatever Bascik produced. There is no conflict, and no coordination required between them.

html
<!-- HTMX and Alpine attributes work inside Bascik components without modification -->
<button hx-get="/api/items" hx-target="#list" hx-swap="innerHTML">
  Load items
</button>

<div x-data="{ open: false }">
  <button @click="open = !open">Toggle</button>
  <p x-show="open">Visible when open is true</p>
</div>

Vue and React

Full-featured frameworks like Vue and React solve a different problem: client-side applications with complex reactive state, component trees, and client-side routing. They ship a significant JavaScript runtime (~40–100+ KB), require a bundler, and introduce a complete component model with lifecycle hooks, reactivity systems, and state management conventions.

On many pages, much of that client machinery is unneeded. The framework runtime loads and runs on every page visit in exchange for features the page may not require.

Bascik's component model lives entirely at build time. There is no runtime equivalent. A <site-nav> tag in source becomes a <nav> element in output, no JavaScript involved.

Svelte

Svelte is the framework whose single-file component format looks most like Bascik's. A .svelte file is <script> + markup + <style>, scoped styles are the default, and the compiler strips the framework syntax. The resemblance stops at the output.

Svelte compiles components to JavaScript that manages reactive state and DOM updates in the browser. In SvelteKit, each page is rendered to HTML on the server (or prerendered at build time), then hydrated in the browser, and a client-side router takes over later navigations. By default, then, a page needs that compiled output to become interactive, and a page with reactive state ships JS for the reactivity system plus JS for the application logic itself.

SvelteKit lets you turn this off per page with export const csr = false. A page with CSR disabled ships no JavaScript, but the <script> tags in its Svelte components are removed, forms cannot be progressively enhanced, and links become full-page navigations. At that point you are writing Svelte templates to produce static HTML, which is what Bascik does with vanilla HTML files, with component <script> blocks that still run, scoped per instance.

Bascik's output for an equivalent component is a static HTML file with no JavaScript added by Bascik. There is nothing to hydrate, no reactive tree to initialize, no framework-managed DOM.

What Svelte adds to a page by default:

  • A compiled JavaScript bundle per component (size varies; runtime helpers are shared across the app)
  • A reactivity model ($state, $derived, $effect) that requires JavaScript to function
  • Template syntax ({#if}, {#each}, {@html}) that resolves to JavaScript on the client, or to server-rendered HTML when the page is prerendered

For content sites and documentation portals, the closest Svelte analog is SvelteKit in static-output mode (adapter-static). By default, SvelteKit still ships JavaScript there for hydration and client-side navigation, unless you opt each page out with csr = false. Bascik's output for equivalent pages is vanilla HTML with none of that overhead, and no per-page opt-out to remember.

Astro

Astro is the closest comparison. Like Bascik, it compiles component-based markup to static HTML and ships no framework runtime by default, so the output is similar. The difference is authoring and what stays optional:

  • Template language. Astro components are .astro files with a JavaScript frontmatter fence and JSX-like expressions. Bascik components are vanilla .html files, used by filename as a custom tag, with build-time logic in <script data-bascik-build>.
  • Interactivity. Astro adds client JavaScript through islands: a UI framework component hydrated with a client:* directive. In Bascik, interactivity is a plain <script> in the component, scoped per instance, with no framework to hydrate.
  • Content and tooling. Astro brings content collections, integrations, and a Vite-based pipeline. Bascik has none of those: Markdown, data, and collections are read in build scripts with Node.js, and the pipeline is a single build step.
  • Ecosystem. Astro has a large integration ecosystem and can host React, Vue, or Svelte islands. If you need those, Astro is the better fit.

For a side-by-side conversion guide, see From Astro.

Next.js

Next.js is a React meta-framework that adds routing, server-side rendering, static site generation, and a full bundling pipeline on top of React. It is a powerful and complete system, and most of that power is aimed at applications with complex client-side state, authentication, API routes, and real-time data.

Many teams reach for Next.js because it is familiar and well-supported. The tradeoff is that every page ships 80+ KB or more of React runtime regardless of whether the page uses any client-side reactivity. Its conventions also gradually pull projects toward client-side patterns even for pages that could remain simple HTML, and auditing what actually reaches the browser gets harder over time.

For many projects, that is simply more client framework than needed. Bascik gives you a streamlined, high-performance alternative. You write vanilla HTML, CSS, and JavaScript. Components are reused at build time. The output is a dist folder of clean files you can open and verify file by file. There is no client runtime to load, nothing to hydrate, letting you write the standard HTML, CSS, and JavaScript you already know. Google's Core Web Vitals (LCP, INP, CLS) are directly affected by JavaScript that blocks rendering; Bascik's output has none of that overhead.

What Bascik offers for these projects:

  • Plain HTML, CSS, and JS authoring with component reuse. No JSX, no hooks, no framework model to adopt.
  • Build output you can open, read, and verify file by file.
  • Static pages that score well on Core Web Vitals without any optimization work.

Static Site Builders: Hugo, Eleventy, Jekyll

Traditional static site builders such as Hugo, Eleventy, and Jekyll focus on content pipelines: Markdown collections, templates, front matter, taxonomies, and data-driven page generation.

Bascik overlaps with them at the output level, all of these tools can ship plain static HTML, but the authoring model is different. Bascik stays close to hand-written HTML pages and reusable HTML components. It does not require a separate template language, collection system, or front matter format just to reuse a header, card, or footer.

The Key Difference

Bascik ships the HTML you wrote, element for element, so the semantic HTML you choose (a <nav>, a <button>, a <details>) reaches the browser unchanged, with no component wrapper or hydration markup around it.

ToolRuntime shippedComponent model or APIs requiredAttribute / source syntaxRequires server
BascikNoneOnly the components you create, plus slots and propsStandards-valid data-bascik-* attributes, consumed at build timeNo
Next.js80–100+ KB (React + hydration)React component model, routing, and Next.js conventionsJSX, React hooks, Next.js file conventionsNo (SSG) / Yes (SSR)
HTMX~14 KBRequest, target, swap, trigger, and history conceptshx-* custom attributes interpreted at runtimeUsually
Alpine.js~16 KBAlpine state and directive modelx-* and @* directives interpreted at runtimeNo
petite-vue~5 KBVue reactivity and directive modelv-* and @* directives interpreted at runtimeNo
SvelteCompiled JS bundle (varies)Svelte component model and reactivity ($state, $effect).svelte file format with compiler-resolved directivesNo
AstroNone by default; islands opt in.astro components, frontmatter, and client:* directives for islands.astro templates with JSX-like expressionsNo (static) / Yes (SSR)
Vue / React40–100+ KBFramework component model, lifecycle, and state APIsVue directives/templates or React JSXNo
Hugo / Eleventy / JekyllNoneTemplate syntax, content collections, front matter, generator conventionsBuilder-specific templating languagesNo

The browser can parse Bascik's source without needing to understand a new runtime language: custom tags are valid custom-element-shaped HTML names, and build instructions use the web platform's data-* convention. Bascik resolves both before deployment. By contrast, runtime directives such as hx-get, x-data, and v-scope only gain behavior after their library's JavaScript loads.

Dynamic Edge Deployments

Modern frameworks like Next.js, Astro, and SvelteKit often provide adapters for edge serverless platforms like Cloudflare Pages or Workers. They achieve dynamic behavior by packaging serverless functions alongside static assets.

Bascik supports this same unified edge deployment model via deployment adapters (such as @bascik/adapter-cloudflare or custom adapters). Running bascik --build --target cloudflare partitions your application into:

  1. CDN static assets: pure static HTML pages, CSS, and client-side assets served directly by Cloudflare's edge cache with zero compute invocation;
  2. Edge worker scripts: pages containing <script data-bascik-server> or <script data-bascik-stream> compile their HTML templates and request-time code directly into a single worker bundle that executes at the edge.

The crucial difference lies in the client footprint. Frameworks like Next.js or SvelteKit require client-side runtimes to hydrate components, manage routing, and handle DOM reconciliations. Bascik streams clean, final HTML from the edge worker directly to the browser. Visitors receive live dynamic data and progressive rendering with zero client hydration overhead.

A vast range of websites and web applications do not require a client framework runtime in the browser. Knowing what each tool is optimized for is the best basis for choosing. Bascik provides component reuse and predictable build output, without a runtime or a new programming model to adopt. You write vanilla HTML, CSS, and JavaScript, get the organizational benefits you would expect from a framework, and ship a dist folder you can fully audit. For the parts of a project that do need client-side behavior, Bascik composes cleanly with HTMX or Alpine.

Combining tools. A common pattern is Bascik for layout components (nav, footer, hero sections) and HTMX or Alpine for specific interactive elements. Each tool does what it is best at, and neither one intrudes on the other's domain.