Zero-dependency vanilla JS/CSS UI framework (placeholder release)
Project description
tinymoon
A lean web framework that turns plain, semantic web content into a polished-looking web app.
Usage
Link the four CSS layers (tokens first) and import the ES modules — no build step, no bundler:
<link rel="stylesheet" href="assets/css/tokens.css">
<link rel="stylesheet" href="assets/css/base.css">
<link rel="stylesheet" href="assets/css/shell.css">
<link rel="stylesheet" href="assets/css/primitives.css">
import { mountShell, createSettings, toast } from "tinymoon";
// or import primitives standalone: import { toast } from "tinymoon/assets/js/toast.js";
const settings = createSettings({ storageKey: "my-app", defaults: { theme: "dark" } });
settings.load();
settings.applyTheme();
const shell = mountShell({
root: document.body,
brand: { name: "myapp", logoHTML: '<div class="wordmark">my<b>app</b></div>' },
routes: {
home: { title: "Home", icon: "library", view: () => HomeView },
},
defaultRoute: "home",
});
Consumer apps can extend the built-in icon set with registerIcons({name: svgString}) — colliding with an existing icon name is a hard error, never a silent overwrite.
Views are plain objects following the contract {root, built, build(), refresh(), setSub?} — the gallery is a complete working app and documents every token, primitive, and extension point (serve the repo root with a static server and open /gallery/).
From Go, the assets ship as an embedded filesystem:
import "github.com/smm-h/tinymoon" // tinymoon.Assets, tinymoon.FS(), tinymoon.Handler()
From Python, the wheel carries the assets; tinymoon.assets_path() returns their directory.
Philosophy
Content-first. You bring plain, semantic content; tinymoon brings the app: shell, typography, widgets, motion. A page of tables and forms dropped into the shell should look like a finished product before you write a line of custom CSS.
Zero build, zero dependencies, zero network. Native ES modules and plain CSS. No bundler, no transpiler, no framework runtime, no npm install to use it, no CDN, no external fonts — everything is vendored. These are enforced by tests, not promised.
No overhead — as a number, not a vibe. No virtual DOM, no reactivity engine, no diffing. Views build their DOM once and mutate data in place; expensive work is cached and lazily loaded. Size budgets are checked in CI so the framework can never quietly bloat.
Gorgeous and coherent — by constraint, not by option. The visual identity is a short list of non-negotiables: sharp corners everywhere, no native browser widgets, a three-font system with monospace for data, a restrained glow language, motion limited to 100–180ms eases. Design tokens let you re-theme and re-accent; they do not let you opt out of the identity. Coherence survives because these are not configurable.
Modular and DRY. Every primitive is an independently importable ES module. Design tokens are the single source of truth for color, spacing, and type — including inside canvas rendering.
You define components; tinymoon defines the language. tinymoon is not a component library you exhaust — it is a component language: an element factory, tokens, a small view contract, a namespaced event bus, and explicit extension points (routes, context-menu providers, settings schema, footer slot). A well-written consumer component is indistinguishable from a built-in.
Very strict. Hard errors over warnings, no escape hatches, fewer options and more opinions. tinymoon ships a conformance checker that consumer projects run as a hard CI gate — external URLs, native widgets, title= attributes, rounded corners, and off-token colors are build failures, not style suggestions. Strictness is what keeps consumer-defined components coherent.
Conformance
tinymoon check scans a directory's .html, .css, and .js files and enforces the framework's non-negotiables as hard errors:
- external-url — no network loads: no
http://,https://, or protocol-relative//hostURLs in HTMLsrc/href/srcset, CSSurl()/@import, or JS import specifiers andfetch()/import()literals (XML namespace identifiers and URLs in comments/prose are fine). - native-control — no native
<select>,<dialog>, or<input type=checkbox|radio|file>, in markup or created from JS; use the framework's primitives. - title-attr — no
title=attributes (SVG<title>child elements are fine); use the tooltip primitive instead. - border-radius — no
border-radius(orborderRadiusin JS) other than0/0px; corners are sharp everywhere. - raw-color — no color literals (hex,
rgb()/rgba()/hsl()/hsla()/oklch()) outside custom-property definitions in:root/html[data-theme=...]blocks; everything else goes throughvar(--token)orcssVar(). (Named CSS colors are not checked.)
Run it against your project's web directory:
uvx tinymoon check --dir ./web
or install it once with uv tool install tinymoon and run tinymoon check --dir ./web. The --dir flag is required — the checker never scans the current directory implicitly.
It prints one line per violation (path:line: [rule-id] message) plus a summary, and exits non-zero if anything is found. There is deliberately no --skip, --ignore, warning mode, or any other bypass — a violation is a build failure.
If a specific URL genuinely must be exempt, add it to a tinymoon-allowlist.txt file at the scanned directory root — one exact URL per line, # comments allowed. The allowlist is a reviewable file in your repo, not a CLI flag.
Use it as a hard gate in CI:
- run: uvx tinymoon check --dir ./web
The step fails the build on any violation; there is nothing to configure and nothing to bypass.
Install
npm:
npm install tinymoon
PyPI:
pip install tinymoon
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tinymoon-0.2.0.tar.gz.
File metadata
- Download URL: tinymoon-0.2.0.tar.gz
- Upload date:
- Size: 159.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7a5174b8bba4ce683bd8b4faff935765ca5407e75a28cbd6c521782566f14c80
|
|
| MD5 |
f5db5be147634998c490c24db6cedd74
|
|
| BLAKE2b-256 |
b982f60356843087128469e38b06b7472bfbfab800c7c7fabf9f5ba0b08b1a2f
|
Provenance
The following attestation bundles were made for tinymoon-0.2.0.tar.gz:
Publisher:
publish.yml on smm-h/tinymoon
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tinymoon-0.2.0.tar.gz -
Subject digest:
7a5174b8bba4ce683bd8b4faff935765ca5407e75a28cbd6c521782566f14c80 - Sigstore transparency entry: 2162968968
- Sigstore integration time:
-
Permalink:
smm-h/tinymoon@6190f9712f2ea62548c4981467129f03e7773389 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/smm-h
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6190f9712f2ea62548c4981467129f03e7773389 -
Trigger Event:
release
-
Statement type:
File details
Details for the file tinymoon-0.2.0-py3-none-any.whl.
File metadata
- Download URL: tinymoon-0.2.0-py3-none-any.whl
- Upload date:
- Size: 140.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5493d004f699d546a9c5a28fb82136ab340e861ea806b9434e9c2752fc2ddd05
|
|
| MD5 |
c9376da2270524bb0c61008e2a15403e
|
|
| BLAKE2b-256 |
f6b68c3a25c53db3b7097ee727103aeff986c80a2b121e66d86a61f3c6795c2a
|
Provenance
The following attestation bundles were made for tinymoon-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on smm-h/tinymoon
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tinymoon-0.2.0-py3-none-any.whl -
Subject digest:
5493d004f699d546a9c5a28fb82136ab340e861ea806b9434e9c2752fc2ddd05 - Sigstore transparency entry: 2162969093
- Sigstore integration time:
-
Permalink:
smm-h/tinymoon@6190f9712f2ea62548c4981467129f03e7773389 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/smm-h
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6190f9712f2ea62548c4981467129f03e7773389 -
Trigger Event:
release
-
Statement type: