Use Markless without a server
Run a Markless component in a plain Vite app with five small files, two packages, and no server.
Last page said the same component renders anywhere. The smallest place is one browser tab.
You need five small files and two packages: @markless/core and vite. The build gives you plain static files.
Press Run, then click the button that shows up.
Where does my component end up?
Press Run to open the page. Then click Count 0 inside it.
The page's HTML right now
<body>
<div id="app"></div>
...
</body>index.html
<!doctype html><html lang="en"> <head> <meta charset="utf-8" /> <title>My Markless app</title> </head> <body> <div id="app"></div> (empty) <script type="module" src="/src/main.ts"></script> </body></html>src/main.ts
import { render } from '@markless/core';import App from './App.tsrx'; const target = document.querySelector('#app');if (!target) throw new Error('Missing #app'); await render(App, { target }); (not run yet)src/App.tsrx
import { state } from '@markless/core'; export default function App() @{ let count = state(0); <button onClick={() => count++}>Count {count}</button>}- noteNothing ran yet. The page is empty until you press Run.
Simplified. Run stands for opening the page: the browser loads index.html, which runs main.ts. The HTML view shows only the body. No server takes part.
Notice that App runs once, in the browser, and fills the empty #app.
Build it
Create package.json
{
"name": "my-counter",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
}
}Then install the two packages:
npm install @markless/core viteAdd index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My Markless app</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>Add vite.config.ts
The markless() plugin runs the compiler on your .tsrx files.
import { markless } from '@markless/core/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [markless()],
});Add src/main.ts
render() runs App once and puts the result inside #app.
import { render } from '@markless/core';
import App from './App.tsrx';
const target = document.querySelector('#app');
if (!target) throw new Error('Missing #app');
await render(App, { target });Add src/App.tsrx
import { state } from '@markless/core';
export default function App() @{
let count = state(0);
<button onClick={() => count++}>Count {count}</button>
}Run it
npm run dev
Open http://localhost:5173 and click Count 0. Notice that only the button text changes.
To build for production, run npm run build. The dist/ folder holds index.html and a build/ folder of JavaScript files. Any static file host can serve dist/.
Next: What if you want many pages, each with its own URL? Quick start →
