simai/ui is the built SIMAI Framework: Core and the Loader, components,
utilities and Smart Components, ready to serve as static files from distr/.
Nothing here is edited by hand. The source is
simai/ui-source, and
simai/ui-builder builds it
reproducibly into this repository.
Documentation (Russian): https://ui.simai.io/
A release is a commit of this repository, named ui-<first 12 hex digits>:
the Build: … commit that wrote distr/. There are no tags and no version
numbers to pick from. To find a release:
git log --grep '^Build:'lists them, newest first;contracts/releases/ui-<id>.lock.jsonrecords what each one was built from (the ui-source and ui-builder revisions) and the digests of what it holds;- CHANGELOG.md says what changed, newest first.
Pin a release, never main: main moves with every release, and a page that
follows it changes without notice.
From jsDelivr, at a release commit:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/simai/ui@<release-commit>/distr/core/css/core.css">
<script>
window.sfPath = 'https://cdn.jsdelivr.net/gh/simai/ui@<release-commit>/distr/';
</script>
<script src="https://cdn.jsdelivr.net/gh/simai/ui@<release-commit>/distr/core/js/core.js"></script>Or from your own copy: serve distr/ as it is, without renaming anything
inside it, and point sfPath at it:
<link rel="stylesheet" href="/distr/core/css/core.css">
<script>window.sfPath = '/distr/';</script>
<script src="/distr/core/js/core.js"></script>core.css is linked by the page: the Loader does not add it, and without it
every component draws without the theme's tokens. sfPath is set before
core.js; a page that leaves it out falls back to main on jsDelivr and says
so in the console.
Then write the markup. The Loader finds the components and utility classes the page uses — including ones added later — and loads only their files:
<sf-button text="Сохранить"></sf-button>
<div class="flex gap-1 p-2 bg-surface-1 radius-2">…</div>Smart Components are in distr/smart and are found under sfPath without
further configuration. window.sfSmartPath remains only for pages that still
serve the archived simai/ui-smart from its own root.
Components owned by a product are shipped as component packages, outside this distribution, and declared by the page:
<script>
window.SF_BOOT_CONFIG = {packages: {larena: {base: '/distr-larena/'}}};
</script>The first one is Larena's (sf-table, sf-data-view, sf-property-view,
sf-admin-menu), built from simai/larena-ui and published as an archive with
its receipt on that repository's GitHub releases. A package is built against
one Framework release; serve the two together.
distr/core/— the runtime: Core, the Loader, the Smart base, core CSS (core.css, andutility.full.cssfor pages that want every utility at once), and the public contracts indistr/core/contracts/(composition formats, ports, public CSS variables, the public JS API);distr/component/— components and the assets Smart Components draw with;distr/smart/— Smart Components;distr/utility/— one module per utility family;distr/rule/— the Loader's rules (rule.json).
Every text file has a .gz twin, byte-identical whoever builds it.
A site with a build step may plan the assets of its first frame instead of letting the Loader discover them:
python3 scripts/plan-framework-assets.py --html build/index.html --ui-root .The planner reads the built HTML by the same rules (distr/rule/rule.json),
resolves their dependencies and prints a deterministic list of CSS and JS files
and the value for window.SF_PRELOADED. A page that passes it is ready from
that plan alone; what is added to the page later is still found by the Loader.
A resource the markup cannot show may be declared with
data-sf-require="utility.<name>|component.<name>|smart.<name>".
The Framework's CSS lives in named layers. A project that adds its own declares them deliberately around these:
@layer sf.reset, sf.tokens, sf.base, sf.utilities, sf.components, sf.states;What a release renames or retires is recorded in the change journal of
simai/ui-source (contracts/changes/journal.json), with the date the old
name leaves. Run its scripts/sf-upgrade.mjs on a project to find every old
name, rewrite what is mechanical and list the rest. Names in use are noted at
runtime in SF.deprecations.
distr/— the distribution;contracts/— release locks, the Framework registry and its owner inputs, generated by the release;scripts/— the release gate and its checks, and the asset planner;docs/releases/— notes of the numbered releases before release commits; docs/documentation-source-contract.md describes the registry projection documentation systems read.
Apache License 2.0 (LICENSE, NOTICE); code published before the change keeps its MIT terms, as NOTICE says. Third-party components are listed in THIRD-PARTY-NOTICES.md.