Monorepo for the MeoNode packages.
| Package | Path | Description |
|---|---|---|
@meonode/ui |
packages/ui |
JSX-free React component composition with CSS-first props and a theme engine. |
@meonode/compiler |
packages/compiler/npm |
SWC WASM plugin that pre-partitions @meonode/ui call sites at build time. |
@meonode/mui |
packages/mui |
@mui/material wrappers for the BaseNode runtime. |
Documentation lives at ui.meonode.com.
packages/compiler is the Rust workspace and its tooling — it is private and
never published. The published @meonode/compiler is packages/compiler/npm,
which carries only the built .wasm and a README, so the two are separate
workspace members.
Two fixture apps sit deliberately outside the workspace and install their own
dependencies: packages/ui/tests/rsc-fixtures/next-app and
packages/compiler/e2e/{next-app,vite-app}. They pin their own React and Next
versions on purpose, which is the point of them.
bun install
bun run build # compiler wasm, then ui, then muiOrder matters: ui's compiled test mode loads the plugin that build:compiler
produces.
bun run lint
bun run test:ui # unit suite, plain and through the real plugin
bun run test:compiler # cargo tests plus the wasm ABI smoke test
bun run check:drift # generated Rust tables still match ui's CSS property set
bun run test:rsc # Next RSC suite, plain and compiled
bun run test:e2e # Next + Vite plugin-on/off paritytest:rsc needs the fixture installed first:
bun run --filter @meonode/ui prepare:rsc-fixtureThat step also copies the freshly built .wasm over the fixture's registry
copy, so the compiled RSC run exercises the plugin from this checkout rather
than the last published one.
Changesets. Describe the change and the bump it wants:
bun run changesetCommit the generated .changeset/*.md alongside the code. CI requires one on
any pull request touching a published package — use bunx changeset add --empty
for changes that ship nothing.
Merging to main opens a "Version Packages" pull request with the bumps and
changelog entries. Merging that publishes to npm via trusted publishing and
tags each released package as @meonode/<pkg>@<version>.
For a prerelease line:
bunx changeset pre enter beta
# ... land changes as usual ...
bunx changeset pre exitui, mui and compiler reference each other by ordinary semver range, not by
workspace:*. The installer still links them to the local packages, so every
suite runs against the code in the same commit, and Changesets keeps the ranges
current when a package is bumped.
The reason to avoid the workspace protocol here is that these are
devDependencies and npm publish — which is what changeset publish calls —
does not rewrite workspace:* into a real version the way pnpm and yarn do. It
would ship verbatim in the published package.json, where nothing can resolve
it.
mui's peerDependencies entry for @meonode/ui is a published range too, and is
rewritten automatically when a ui release leaves it.