MCP Server
Runtime Constraints
These rules apply to browser_bundler apps — the default and the only mode where Webase compiles your source. external_static apps have full freedom (any toolchain, any deps); only the Data API conventions apply there.
Every MCP session should call get_runtime_constraints first. It returns this same content as machine-readable JSON so the agent can program against it.
Entry point
The bundler picks the entry from this ordered list. Provide one.
src/index.tsxsrc/index.jsxsrc/index.tssrc/index.jssrc/App.tsxsrc/App.jsx
Import map
React 19 and react-router-dom are externalized via an import map injected into the wrapped HTML. Don't bundle them — just import bare.
{
"react": "https://esm.sh/react@19",
"react/": "https://esm.sh/react@19/",
"react-dom": "https://esm.sh/react-dom@19",
"react-dom/": "https://esm.sh/react-dom@19/",
"react-dom/client": "https://esm.sh/react-dom@19/client",
"react-router-dom": "https://esm.sh/react-router-dom?deps=react@19,react-dom@19"
}
Other npm packages
Two ways to add an external package:
-
Direct esm.sh URL in source:
import confetti from 'https://esm.sh/canvas-confetti' -
Declare in
package.jsonand use a bare import; the bundler auto-maps each dep tohttps://esm.sh/<name>@<major>?deps=react@19,react-dom@19.{ "dependencies": { "chart.js": "^4.4.0" } }
There is no npm install at runtime. Don't ship a node_modules.
Tailwind
Loaded via the CDN script tag — <script src="https://cdn.tailwindcss.com"></script> — which the bundler injects into the HTML wrapper.
- Don't create a
tailwind.config.jsfile — it has no effect. - Custom config goes inline inside
public/index.html:<script> tailwind.config = { darkMode: 'class', theme: { extend: { colors: { brand: '#16a34a' } } } } </script> - Webase preserves the contents of
<head>frompublic/index.html(minus charset / viewport / cdn-tailwind, which the wrapper provides).
Routing
Use HashRouter from react-router-dom. The preview iframe has no server to handle history fallbacks; HashRouter keeps routing client-side.
import { HashRouter, Routes, Route } from 'react-router-dom'
export default function App() {
return (
<HashRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/posts/:id" element={<Post />} />
</Routes>
</HashRouter>
)
}
CSS
CSS files are converted into runtime style-injectors at bundle time, so you can import './styles.css' from any module and the styles get appended to document.head at runtime. There's no separate stylesheet output.
Application data
Define data models with create_data_model + add_data_field. Generated apps read and write records via the Data API. localStorage is for UI preferences only — never application data.
Dark mode
Use Tailwind's darkMode: 'class' strategy in your inline tailwind.config. Toggle by adding or removing the dark class on document.documentElement. Persist user choice in localStorage.