
Scope note: "threeui" names several unrelated projects. This review covers the active one: ThreeUI by Meng To / designcodeio (threeui.com, github.com/MengTo/threeui) — a React + Three.js/WebGL component catalog with a free Community tier and a paid Pro tier.
At least three other projects share the name:
an archived
poki-archive/three-uicanvas layera small unrelated
three-uinpm packagepetekp/three-ui, an experimental WebGL library exploring Chrome's HTML-in-canvas origin trial
Looser matches exist too (an AR-focused three-ui-ar package, for one). The namespace is crowded — say so if you meant a different project.
This review is checked directly against the live GitHub repo: README, file tree, and repo metadata, as of this writing. Pro internals aren't published, so this isn't a source-code audit of the private main project.
One limit worth naming: the install commands below are copied from the README, not executed. This environment has no network access to run npm install directly, and a registry search for @designcodeio/threeui didn't return an independent hit either way.
1. What it is
ThreeUI is a catalog of shader-driven UI pieces: hero sections, WebGL backgrounds, animated buttons, and full page templates. It ships three ways — a browsable site, an installable npm package, and, for Pro subscribers, a CLI that writes raw source into your project.
The public repo is the Community edition: 50 parent components across 111 routes, totaling 164 browse results (141 free variants plus 23 singleton components). It runs the same app shell, navigation, live renderers, and variant pickers as the main product.
The Community edition isn't Pro features switched off — it contains no authentication, account-state, or checkout code at all. The only thing actually missing is the Pro and Beta component implementations themselves.
2. Getting started
Prerequisites: not stated anywhere in the public docs. Neither the README nor the repo's rendered file tree exposes a Node engine constraint or a React peer-dependency range. Check package.json directly in the repo before pinning versions in a real project.
Option A — install as a dependency
npm install @designcodeio/threeuiimport { AtTheHorizon } from "@designcodeio/threeui";
import "@designcodeio/threeui/style.css";
export function Hero() {
return <AtTheHorizon />;
}For a smaller import graph, pull components from their subpath instead of the package root:
import { AtTheHorizon } from "@designcodeio/threeui/components/AtTheHorizon";One gotcha: some components render a full HTML document. They expect their runtime assets at fixed root-relative URLs — the same ones the hosted preview uses.
Copy the relevant files from node_modules/@designcodeio/threeui/lib-dist/assets/ into your public directory, or override the component's sourceUrl/assetBaseUrl prop. Treat this as an integration step, not a drop-in install.
Option B — run the Community catalog locally
npm install
npm run devBefore shipping any change, run the full check:
npm run buildThis runs the publication-boundary, type, and production-build checks together.
Getting Pro components
Pro source isn't published to npm. Subscribers authenticate in the browser, then pull an entitled source bundle through the CLI:
npx @designcodeio/threeui-cli add cross-beamThe CLI won't overwrite modified project files unless you pass --force. Run npx @designcodeio/threeui-cli --help for login, logout, and destination options.
3. Architecture review
Community | Pro | |
|---|---|---|
Distribution | npm package ( | CLI download ( |
Source visibility | Published; browsable in | Not published; pulled per-component after auth |
Access check | None — public package | Live entitlement check on every CLI request |
Where it lands | Package import from | Raw source files copied into your project |
Update model | Standard npm version bump | Re-run the CLI per component; independent of the CLI's own version |
License | MIT (code + Community imagery), OFL (fonts), MIT (bundled Three.js runtime) | Set by your subscription terms, not the repo's OSS license |
Two build targets, one source tree
The repo carries separate vite.config.js and vite.lib.config.js files, plus split tsconfig.json / tsconfig.lib.json configs.
The catalog website and the publishable npm library are built from one shared component tree but two separate configs. A change to library-only build settings — externals, output format — doesn't touch the app build, and vice versa.
The Community edition is generated, not forked
A private main repo holds everything — Community, Pro, and Beta. This public repo is refreshed from it by a sync job: npm run sync:community -- /path/to/main-threeui.
That job:
fails closed instead of erring open
filters Pro and Beta content before building the public import graph
strips restricted font assets
writes three generated files:
public/community-sync-report.json— a parity/count reportpublic/source-code.json— the source bundle behind the in-app "Code" tabsrc/data/shaders.tsx— the catalog/import file
The private repo runs this after every push to its main branch. Rather than pushing straight here, it commits to an automation/community-sync branch and opens a reviewed pull request. A sync with no public-facing change doesn't open one at all, so the public history stays clean.
If the filter step fails, the job errors instead of publishing a partial result. The specific failure it's built to prevent: Pro source leaking into the public repo through an incomplete sync.
Releases infer their own version
A versioned sync PR infers its own semver:
new public components, variants, or controls → minor
removals → major
compatible source-only changes → patch
Merging that PR publishes to npm through trusted publishing with provenance, not a long-lived npm token sitting in CI.
A separate gate runs first: clean build, boundary audit, package creation, anonymous install smoke test. The Pro CLI installer is versioned and released independently of Pro content — a new Pro component doesn't force a CLI bump.
Entitlement checks run live
The CLI's OAuth+PKCE flow fits a public, secretless client — there's no client secret to protect. Its session is stored with owner-only file permissions.
Entitlement is checked on every server request, not once at login. A lapsed subscription stops working immediately, not after some cached grace window.
The license boundary
App code, Community component code, and ThreeUI-authored Community imagery: MIT
Bundled fonts: SIL Open Font License 1.1
Bundled Three.js runtime files: their own MIT license
Remote catalog thumbnails and previews loaded live from threeui.com: not redistributed under the repo's license
The boundary sits between what's checked into the repo and what's fetched live from the site at render time. Everything in the repo — code and imagery alike — ships under MIT; only the live-loaded assets fall outside it.
4. Things to watch
node_moduleswon't show the full picture. Pro source arrives through an authenticated CLI download, not an npm dependency. A dependency scan of a Pro-using project won't surface it.Full-document components assume a hosting layout. Their default asset URLs mirror the hosted preview site's paths. Plan for that coupling during integration.
Some files in the tree are generated, not source.
public/community-sync-report.json,public/source-code.json, andsrc/data/shaders.tsxare written by the sync job. A PR editing them directly would likely get overwritten by the next sync — confirm contribution scope with maintainers first.Activity is light but present. At last check the repo carried 5 open issues and 4 open pull requests against 22 commits total — enough to gauge maintenance pace, not enough to call it a heavily trafficked issue tracker either way.
Third-party listings here are unverifiable. 21st.dev claims ThreeUI publishes an official shadcn registry at threeui.com, but its own component count for that listing swung between 109, 44, and 33 across fetches minutes apart. threeui.com renders client-side, so its content isn't independently fetchable either. Treat this channel as unresolved, not confirmed.
Comments (0)
Login to post a comment.