@tmrw/vite
TypeScript icon, indicating that this package has built-in type declarations

0.0.9 • Public • Published

@tmrw/vite

A Vite plugin that integrates TomorrowJS with TSX/JSX, SSR, SSG, file-based routing, nested layouts, and enhanced hot module reloading (HMR).

Overview

Modern web development often presents a choice between the flexibility of frameworks like React or Next.js and the simplicity of DOM-first approaches. TomorrowJS is a minimalist library that enhances vanilla web development with attribute-based bindings, simple state management, and no heavy virtual DOM.

@tmrw/vite bridges the gap, delivering a Next.js-like developer experience—complete with TSX pages, nested layouts, SSR, and optional SSG—while preserving TomorrowJS's lean philosophy. It allows you to:

  • Write pages and layouts as TSX/JSX components without manual imports
  • Dynamically render content on the server (SSR) during development and production
  • Optionally pre-generate static HTML for all pages at build time (SSG)
  • Organize your application using file-based routing and nested layouts
  • Benefit from enhanced HMR that tries to patch the DOM on changes, minimizing full reloads and preserving application state

This plugin aims to offer a modern developer experience in a lightweight, DOM-centric environment.

Key Features

1. TSX/JSX Support

Use familiar JSX syntax for writing pages and layouts. You don't have to import TomorrowJS utilities in every file—just focus on your markup and state updates.

2. Server-Side Rendering (SSR)

Enjoy SSR out-of-the-box. On npm run dev, pages are rendered on the server. This makes local development feel like working in a robust, production-ready environment.

3. Static Site Generation (SSG)

Set ssg: true in the plugin options to pre-generate static HTML for all routes at build time. Perfect for deploying fully static sites to a CDN.

4. File-Based Routing & Nested Layouts

Place page.tsx files in an app/ directory to define routes (app/about/page.tsx -> /about). Add layout.tsx files in directories to wrap child pages. Build complex page structures without explicit routing code.

5. Enhanced HMR

On code changes, the plugin tries to re-import changed modules, re-render the current page and layouts on the client, and perform minimal DOM patches. This means fewer full reloads and better preservation of current state—an even smoother development experience than vanilla Vite HMR.

Installation

npm install @tmrw/vite @tmrw/core

Getting Started

1. Project Structure

Example:

project/
├── app/
│   ├── layout.tsx
│   ├── page.tsx
│   └── about/
│       ├── layout.tsx
│       └── page.tsx
├── main.ts
├── vite.config.ts
└── package.json
  • app/page.tsx: Root page for /
  • app/about/page.tsx: Page for /about
  • app/layout.tsx: Global layout wrapping all pages
  • app/about/layout.tsx: Nested layout wrapping pages under /about

2. main.ts

import { createStore, registerAction, initTmrw } from "@tmrw/core";

const store = createStore({ title: "Hello TomorrowJS", count: 0 });
registerAction("incrementCount", ({ store }) => {
  const current = store?.get("count") || 0;
  store?.set("count", current + 1);
});

initTmrw({ store, root: document.getElementById("app")! });

3. vite.config.ts

import { defineConfig } from "vite";
import { tomorrowPlugin } from "@tmrw/vite";

export default defineConfig({
  plugins: [
    tomorrowPlugin({
      appDir: "./app",
      ssg: false,
    }),
  ],
});

4. Run dev server

npm run dev

Open http://localhost:5173. You'll see your page rendered on the server. Changes to app files should update instantly thanks to HMR, often without a full page reload.

Options

  • appDir (string, default: 'app'): The directory containing your pages and layouts. The plugin expects page.tsx files to define routes and optional layout.tsx files for nested layouts.
  • ssg (boolean, default: false): If true, running npm run build will statically pre-render all discovered pages into dist/, producing ready-to-serve HTML files. If false, pages are rendered at runtime in production SSR mode.

How It Works

1. TSX Runtime

The plugin configures the Vite ESBuild pipeline to use a custom JSX runtime. This runtime returns a lightweight tree that is converted to HTML on the server for SSR or SSG.

2. SSR in Dev & Prod

During development, Vite's dev server calls the plugin's SSR middleware. It finds the corresponding page.tsx file for the requested URL, along with any parent layout.tsx files. It then:

  • Creates a store (via TomorrowJS) and calls the page's render() function to produce a VNode tree
  • Wraps the tree with nested layouts
  • Converts the final tree to HTML and serves it

In production, a similar process occurs (you can run Vite's preview server or integrate with a Node server), providing SSR by default.

3. SSG (Optional)

When you run npm run build with ssg: true, the plugin:

  • Discovers all routes by finding page.tsx files
  • For each route, it simulates SSR at build time, producing an HTML file in dist/
  • Deploy dist/ to a static host or CDN for extremely fast, CDN-delivered pages

4. HMR Integration

The plugin enhances the default HMR:

  • On code changes, instead of always doing a full page reload, it tries to re-import the affected modules on the client
  • It re-renders the current page and layouts in memory and attempts a minimal DOM patch
  • If the structure of the page changed too much, it falls back to a full reload, ensuring consistency

This means that when you tweak text or minor structure, the page updates in place, preserving scroll position, store data, and other UI states.

Q&A

Q: Do I need React or a similar framework?
A: No. This plugin uses TomorrowJS and a custom minimal TSX runtime. You can write JSX/TSX, but there's no virtual DOM or React dependency. It's a simpler, DOM-first approach.

Q: Can I use client-side routing or complex SPA patterns?
A: TomorrowJS encourages minimalism. While you can navigate between pages via standard links, if you need SPA-like transitions, you may implement custom code or another lightweight router. This plugin focuses on SSR, SSG, and file-based routing for multi-page apps.

Q: Will it work with TypeScript?
A: Yes. TypeScript is fully supported. The plugin encourages a typed environment, and TomorrowJS's store also benefits from strong typings.

Q: How does it handle dynamic routes (e.g., [slug].tsx)?
A: The plugin maps [param] to :param in routes, similar to Next.js. So app/blog/[slug]/page.tsx maps to /blog/:slug. The SSR logic matches routes accordingly.

Q: What if I rely on heavy client-side interactivity?
A: TomorrowJS offers attribute-based bindings for reactivity. You can register actions with data-t-on attributes. If you need more complexity, integrate your preferred state management or UI libraries. This plugin does not limit your approach.

Advanced Tips

State Preservation with HMR

Because we do not tear down and re-initialize the store on every change, your TomorrowJS store state remains intact. Minor edits to your page or layout modules update the DOM without losing application state, improving development speed and comfort.

Partial Hydration or Islands

The plugin doesn't do partial hydration by default. Everything is SSR'd and then TomorrowJS enhances it. If you want island architecture or partial hydration, you can compose those patterns on top of this approach by controlling where initTmrw() runs or how you structure your pages.

Combining with External Libraries

You can add other libraries for AJAX, animations, or state management. The plugin doesn't interfere with standard JS usage in the browser or Node environment.

Example Repository

A sample project structure and code snippet are provided in the plugin's documentation. After installing, simply:

npm run dev

Open http://localhost:5173 and see your pages live, SSR rendered, and TSX-based. Edit app/page.tsx and watch the page update instantly.

License

MIT

By following this guide, you can confidently adopt @tmrw/vite for a modern, TSX-based TomorrowJS development experience that feels as powerful and convenient as major frameworks, but remains lean, DOM-first, and fully in line with TomorrowJS's philosophy.

Package Sidebar

Install

npm i @tmrw/vite

Weekly Downloads

6

Version

0.0.9

License

MIT

Unpacked Size

47.9 kB

Total Files

29

Last publish

Collaborators

  • crazywolf132