🧩 Design-Information-Modeling for Kit-of-Parts 🏘️
You want to 🧩 the next 🏘️🏛️🏢🏭🏫🏨⛪🕌 with 🤖? But 📐🔢🗣️👥🖱️⌨️ takes all your ⌚? Then try to 🧠 the 🧬 and let semio 💉🖥️✒️🖨️🪄🚀
Note
Are you a user or new to semio? Then you might want to first check out our docs 📖
Glad to see you!
Let me walk you through 🚶
- 🛍️ Products
- 📄 Specs
- 🦑 Repo
- 🧑💻 Development
- ♻️ Ecosystems
- 📦 Components
- 🏘️ Examples
- 💯 Brand
- ⚖️ License
- 🔒Security
- ✨ Contributors
- 📊 Stats
🛍️ Products ↑
Do you wonder how semio is interopable? The reason are shared specification, ecosystems and components 🪢
Work-in-progress artifacts stay bundled with the active ticket workspace so teams can trace temporary data without hunting global temp locations.
✏️ sketchpad ↑
sketchpad is a simple-to-use, accessible and browser-based user interface for semio🖱️
It is the digital pencil for sketching plans and digital scalpel for building models in semio ✍️
Sketchpad uses semantic borders to communicate interactive element edges and window boundaries. Windows are separated from the canvas edge and from each other by a single spacing unit, and each window is outlined by a continuous border.
Each window has a consistent set of icon actions (open in new window, maximize/minimize, close) that stays in the same position across window kinds.
Sketchpad uses background levels to visually distinguish the base canvas from windows, panels, and transient UI surfaces.
Sketchpad is a multi-window workspace: each app defines which window kinds it supports and window layouts persist so users can restore their preferred arrangement.
In a multi-window workspace, exactly one window is active and its surface uses the active background color; table views follow the active window surface background.
Hover and selection cues stay consistent across Home, Kit, Design, Type, Quality, Docs, and Feedback so focus follows your pointer and selection across the workspace.
👥 studio ↑
A studio is a synchronous collaboriation environment for teams to work together in semio 🤝
☁️ cloud ↑
Use any file-hosting platform as an asynchronous Common-Data-Environment 📁
🤖 assistant ↑
The assistant helps you on every step in the design process with semio ✍️
VS Code Extension ↑
The VS Code extension keeps tickets close to daily work with inline close or reopen actions that act on the selected ticket, commit visibility, and concise hover descriptions for quick scanning. Automation tooling rejects invalid arguments and non-file paths so MCP-driven workflows surface mistakes immediately. Ticket creation and iteration starts always request a description, while file lists can be added later when needed. Ticket iteration and finish actions attach git-derived file lists and line totals scoped to the ticket files so progress and impact are visible from the ticket view. Code hygiene diagnostics ignore comment markers inside string literals so snippets and URLs stay clean of false comment warnings. Code hygiene diagnostics flag orphan definitions outside named sections so the file structure stays consistent. The command browser mirrors the repo command and subcommand hierarchy so discovery follows the same structure as the CLI. Problem list entries open in dedicated editor tabs so edits are immediately saveable. Contributor views merge ticket activity and file header credits into a per-person breakdown with line totals, grouped tickets, commits, bundles, and file navigation for quick context. The built-in Explorer adds a Sections panel that lists the current file structure (including JSON object keys), lets you jump to a section on click, supports F2 rename, and provides inline create-child, rename, delete, and drag-move actions.
A batteries-included Grasshopper plugin for semio ⚡
🦏 semio.3dm ↑
A Grasshopper-based integration of Rhino and semio 🔀
🐝 semio.wasp ↑
A Grasshopper-based integration of Wasp and semio 🔀
🦌 semio.monoceros ↑
A Grasshopper-based integration of Monoceros and semio 🔀
🐞 semio.ladybug ↑
A Grasshopper-based integration of Ladybug and semio 🔀
📄 Specs ↑
📦 Kit ↑
A kit is a collection of types, designs, authors, qualities, attributes, and concepts 📦
A kit is either static (a special .zip file) or dynamic (bound to a runtime) 📦
A static kit contains a reserved .semio folder that contains a kit.db sqlite file 💾
The SQL-schema of kit.db is found in ./sqlite/schema.sql 📄
For Inter-Process-Communication (IPC) the JSON-schema in ./jsonschema/kit.json is used 📄
🏘️ Design ↑
A design is an undirected graph of pieces (nodes) and connections (edges) with organizational layers, groups, stats, attributes, and concepts 📐
A design is proto (a protodesign) when it has no parent.
Children of a parent are _subdesigns.
A flat design has no connections and all pieces are fixed ◳
The pieces are placed hierarchically (breadth-first) for every component 🌿
Additional connections which where not used in the placement can be used to validate the computed planes 🛂
🏠 Type ↑
A type is a reusable component with different models, connectors, attributes, concepts, and authors 🧱
A type is proto (a prototype) when it has no parent.
Children of a parent are _subtypes.
A type can be virtual (intermediate type requiring other virtual types to form a physical type), scalable, and mirrorable with stock quantity, unit, and optional location 📍
🔗 Connection ↑
A connection is a 3D-Link between two pieces with the translation parameters gap (offset in y-direction), shift (offset in x-direction) and rise (offset in z-direction), and the rotation parameters rotation (rotation around y-axis), turn (rotation around z-axis) and tilt (rotation around x-axis) 🪢
The translation is applied first, then the rotation 🥈
The two pieces are called connected and connecting but there is no difference between them 🔄
The direction of a connection goes from the lower hierarchy to the higher hierarchy of the pieces ➡️
A connection can have attributes and diagram positioning with x and y offsets 📍
⭕ Piece ↑
A piece is an instance of either a type or a design with id, optional description, optional plane, center position, scale, optional mirror plane, hidden and locked states, color, and attributes 📐
A piece is either fixed (with a plane) or linked (with a connection) 📐
A group of connected pieces is called a component 🌿
The hierarchy of a piece is the length of the shortest path to the next fixed piece 👣
⚓ Connector ↑
A connector is a conceptual connection point with an outwards direction, id, optional description, and t value for diagram ring positioning 🤝
A connector can be marked as mandatory in which case it is required to be connected to a piece 💯
A connector can have a connector port and a list of compatible ports for explicit compatibility control 👨👩👧👦
No port means the default port and no compatible ports means the connector is compatible with all other connectors 🔑
It is enough for one connector to be compatible with another connector to be compatible with each other
A connector can have props that define measurable characteristics and attributes for additional metadata 📏
💾 Model ↑
A model is a tagged url to a resource with an optional description 📄
No tags means the default model 🔑
The similarity of models is determined by the jaccard index of their tags 🔄
🏷️ Attribute ↑
A attribute is metadata with a unique name, an optional value, an optional unit and an optional definition (url or text) 🔤
The name iskebab-cased and with .-separated string similar to toml keys 🔑
No value is equivalent to the boolean true where the name is the category of the attribute 🔑
The unit is a unit identifier 🔢
mmfor millimeter,cmfor centimeter,dmfor decimeter,mfor meter,kmfor kilometerm²for square meter,m³for cubic meter,m⁴for quartic meter°for degree,radfor radianNfor newton,kNfor kilonewton,MNfor meganewton°Cfor degree Celsius,°Ffor degree FahrenheitWfor watt,kWfor kilowatt,MWfor megawatt,GWfor gigawattWhfor watt-hour,kWhfor kilowatt-hour,MWhfor megawatt-hour,GWhfor gigawatt-hourJfor joule,kJfor kilojoule,kcalfor kilocaloriekWh/m²afor kilowatt-hour per square meter per yearm/sfor meter per second,m²/sfor square meter per second,m³/sfor cubic meter per secondPafor pascal,kPafor kilopascal,MPafor megapascal- …
A list of attributes is semantically equivalent to nested dictionaries where the key is the name and the value is the value
🏷️ Tag ↑
A tag is a kebab-cased name 🔤
◳ Plane ↑
A plane is a location (origin) and orientation (x-axis, y-axis and derived z-axis) in 3D space
The coordinate system is left-handed where the thumb points up into the direction of the z-axis, the index-finger forwards into the direction of the y-axis and the middle-finger points to the right into the direction of the x-axis 👈
🔗 Url ↑
A url is either relative (to the root of the .zip file) or remote (http, https, ftp, …) string🌐
A relative url is a /-normalized path to a file in the .zip file and is not prefixed with with ., ./, /, …
🔢 Quality ↑
A quality is a measurement definition with a key, name, description, kind (General, Design, Type, Piece, Connection, Connector), unit information (SI and Imperial), range constraints (min/max with exclusion flags), default value, and optional formula 📏
A quality can be scalable (adjusts with piece scaling) and have multiple benchmarks for performance evaluation 🎯
The kind determines which entities the quality can be applied to using a bitwise enum system 🔢
📊 Benchmark ↑
A benchmark is a performance standard within a quality with a name, optional icon, and range (min/max with exclusion flags) 🏆
Benchmarks provide reference points for evaluating quality measurements against industry or design standards 📈
🏷️ Concept ↑
A concept is a name and order pair that provides semantic grouping for kits, types, or designs 🧠
Concepts enable hierarchical organization and categorization of design elements beyond simple naming 📂
👤 Author ↑
An author has a name and email and can be associated with kits, types, or designs with a rank indicating contribution level 👨💻
Authors provide attribution and contact information for design ownership and collaboration 🤝
📋 Layer ↑
A layer is an organizational grouping within a design with a name, optional description, and color for visual organization 🎨
Layers provide a way to group and manage pieces logically within complex designs 📑
👥 Group ↑
A group is a collection of pieces within a design with optional name, description, color, and attributes 👥
Groups enable semantic clustering of pieces that belong together functionally or conceptually 🔗
⚙️ Prop ↑
A prop is a key-value pair on a connector that references a quality with a specific value and optional unit 🔧
Props define measurable characteristics of connectors using the quality system for standardized measurement 📐
📈 Stat ↑
A stat is a statistical measurement on a design that references a quality with range (min/max) and optional unit 📊
Stats provide computed or measured performance data for entire designs using the quality framework 📈
This git repo has everything that exists in the open semio ecosystem 🤯
⚖️ Principles ↑
Let's start with the rules of thumbs that this codebase was built with 🫰
💾 If something can be written in a single file, then it probably should ✅
I know, the urge to tidy up or separate things is big 🗃️
But try to withstand it 🫥
Out of my experience, it makes development slower, not faster 🐌
A single file is easier for humans and computers to understand 💡
You will be surprised
- by the awesome fill-in-the-middle suggestions of your copilot 🤖
- by the hassle-free context selection for your ai agent 🖱️
- by the smooth refactor experience by just going top-to-bottom ⬇️
- by the beautiful diff for your next code review 🔍
- by the clean git-history when you try to find a certain change 🔁
🙃 Write and read code upside down ✅
Whenever something is referenced it should be above in the source code ⬆️
This means that all the building blocks (functions, classes, components, …) are first defined and then used below ⬇️
If you have a cyclic depedency (really?!) then put the object with lower complexity first 🥇
This means that when you start with unknown code, it is probably best to start on the bottom and go upwards 🖱️
Why? LLMs, reflection, … , work best left-to-write 🤖
But Fill-in-the-Middle training is for free!?
Yeah, if you consider only FiM for code, then yes 🆗
But we want it all!
And is really so hard to start reading a from the bottom?
📑 If a class, function, component, … is only used once, then don't create it ❌
Probably, you learned to group code by classes, functions, components, … even if those definitions are only used once 🥇
It hides the actual complexity and makes it harder to navigate the code 🔍
📺 Inline everything that bearly fits onto the screen ✅
Smaller code, less tokens and easier diffs 🔍
Your ai bill will be lower and the completions will resolve faster 🚀
If you are not sure what the code does, you can ask ai 💬
🗣️ Don't use comments or if you must, only tag code at the end of the line ❌
Smaller code, less tokens and easier diffs 🔍
Your ai bill will be lower and the completions will resolve faster 🚀
If you are not sure what the code does, you can ask ai 💬
📑 Use regions to structure your code ✅
Because you are not using classes, functions, components, … and you are inlining everything, your code will become long 📃
To organize your code, you can use nested regions 📂
In general, our files follow this structure:
- Header
- TODOs
- Imports
- Constants
- CODE
📁 If a folder doesn't make your life dramatically easier, don't create it ❌
We all know this ./src/** folder that has made it into a lot of starters 🚀
Other than feeling cool about using hacky abbreviations, does it really help you to understand the bundle faster and work more efficient on it?
If your bundle contains hundreds of config file and other bundle folders at the root, maybe 🤔
But most likely not ❌
📦 Parts that belong together should be close in the source code ✅
The default code organization is to group kind of structurally similar parts together 📂
All models next to each other, all controllers next to each other, all errors next to each other, …
While this pattern supports structural refactoring, it makes plain extensions harder because you have to search through all the files 🔍
Most changes are plain extensions and not structural refactors 🔄
Further it has the advantage that every LLM-agent only has to predict one big block of code instead of plenty of small ones 🤖
That's why frameworks like React exist or vendoring such as with shadcn is more flexible than dependcenies such as with bootstrap
Cutting components vertically (a bit of logic with a bit of UI) instead of horizontally (all logic, all ui) requires more effort but enhances reusability 🔮
📄 If multiple people work longterm on the same part, then one file for each part should be created ✅
Trust me, it will make collaboration much easier 🔀
🔮 If you don't need an port because something is not likely to be extended soon, don't create it ❌
The main question is the port productive or not?
The pay-off of abstraction happens in the future 🛣️
Every extension profits from a clean port 🚀
Most things are not extended 🪨
If you change your architecture, just design proper ports for something concrete not something potential and reactor it ✍️
🤏 Repeating code is ok if it the repeated code is close in the source code ✅
We are past the time where we copy code for no reason 📃
Actually repeated code can improve the attribute of your copilots suggestion 🤯
The main question is how can your application grow?
If a change requires exponentially more duplication then you'll probably have to fix it 🛠️
If not, then you are probably good 👌
🏷️ Never use `type` for naming enums, ports, or types. Always use `kind` instead ✅
To avoid confusion with the native type concept in Semio, always use kind for naming enums, ports, or types that represent categories or classifications 🏷️
Examples: ArtifactType → ArtifactKind, WindowType → WindowKind, etc. 🔄
🤨 Wait, no high-level advice and only plain numbers, files, folders or close line of codes?
In our understanding, policy-of-thumbs are most useful when they are concrete 🔨
Besides that we are sure you know about KISS (Keep-It-Simple-Stupid), DRY (Dont-Repeat-Yourself) vs WET (Write-Every-Thing-Twice)/RUG (Repeat-Until-Good), YAGNI (You-Aren't-Gonna-Need-It), SoC (Separation-of-Concerns), Avoid Premature Optimization, Law of Demeter, LCHC (Low-Coupling-High-Cohesion), SOLID (SR (Single Responsibility), OC (Open/Closed), LS (Liskov's Substitution), IS (Interface Segregation), DI (Dependency Inversion)), …
But as always, the devil is in the details 😈
Even if 95% of the codebase follows those principles, there are good reasons for the other 5% ⚖️
🚩 Don't worry, you'll figure out the possibilities and make the right choice for the specific problems ✅
🦑 GitKraken ↑
Note
It is free for open-source bundles like this one ❤️
We use GitKraken Desktop as our git client 🖱️
It is the only nice chronological graphical overview for all branches at the same time that we found 🔍
💬 Discord ↑
Most git events are synchronized with our repo channel 💬
It is perfect to find the latest activities and the history 🔍
📢 Release ↑
Every release contains a set of matching specs, components, examples and docs 📦
The release notes follow this format:
SYMBOL TITLE
COMPONENT
- SYMBOL SUMMARY [CONTRIBUTOR]
…
Title symbols:
- 🏗️ Foundational work
- 🛠️ Heavy work
- 🪛 Minor work
- 🐛 Major Bug fix
Description symbols:
- 🌱 Started [not yet ready]
- ➕ Added [ready]
- ⬆️ Updated
- 🔄️ Renamed
- 🔁 Refactored
- 🐛 Bug fix
Before every release the repo is archived 📦
🏷️ Tag ↑
We have two different types of tags:
rYY.MM-Vfor releases (e.gr21.06-1,r23.07-2,r24.12-1,r25.07-1, …)COMPONENT-vMAJOR.MINOR.PATCHfor components which follow the semver versioning scheme (e.gengine-v4.0.2,sketchpad-v1.0.0,grasshopper-v5.4.0-beta, …)
🌿 Branch ↑
The main branch is compressed (squashed history) and acts as the canonical integration branch 🗜️
If a release receives updates after main already progressed, create a parallel release/rYY.MM-V branch for that release and keep it compressed as well 🧵
Every contributor has their own FIRSTNAME general-purpose development branch 🛠️
In GitKraken you will quickly find the latest development branch 👀
Other branches are created for components, specific features or bug fixes 🐛
Usually one person works on one feature at a time and hence the -NAME suffix 📛
🗃️ Commit ↑
Commit messages follow this format:
MAIN-TASK-SYMBOL SUMMARY WORK-SYMBOL
The first symbol encodes the main task of the commit and the last symbol encodes the amount of work (🪛 < 🔨 < 🛠️ < 🏗️) 🧰
📦 Commit as much as you like ✅
Are you worried about committing all those binary application files (.zip, .gh, .blend, .glb, .3dm, …) or the intermediate versions between your ai edits?
Well, normally you should be 💾
But as we archive and squash all commits on every release nothing is lost or polluted 💯
⌛ Push around once an hour ✅
Pushing regularly keeps you extra safe from losing your work 🛟
There are a few services (like Discord) that are automatically updating to what happens in the repo 🔄️
To keep our inbox notifications low, we try to push not more than once an hour ⬆️
🧑💻 Development ↑
Different ecosystems need different tools 🧰
For a complete setup you need:
- Windows 10 or 11
- Visual Studio Code
- Visual Studio 2022 Community
- Rhino 8
- Python 3.13
- Poetry
- Node
If you do not have Python installed, I recommend to install it over the Microsoft Store 🏪
Afterwards you can install poetry with this command:
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python -In the console you will see a warning that the poetry.exe is not installed in the requested location 📁
Then copy the actual path ...\AppData\Local\Packages\PythonSoftwareFoundation...\Roaming\pypoetry\venv\Scripts and add it to your environmental path variable ➕
Then you can run npm run build from the root to build all packages, or run tsx ./build.ts in the Grasshopper directory and add your full path LOCAL_PATH\net\Semio.Grasshopper\Debug\net48 to your GrasshopperDeveloperSettings ⚙️
🎫 Tickets ↑
Contributor workflows use tickets to track each task across iterations, recording prompts, file touch lists, and per-file line diffs so work is auditable and easy to continue.
🧰 Violations ↑
Contributor workflows include an automated code-quality report that highlights inline and multi-line comments (including JSDoc blocks), missing license headers, malformed region blocks, and empty regions before changes are shared. It also enforces module boundaries and domain-neutral terminology for shared UI building blocks, while automated fixes remove empty regions to keep region structure meaningful. Each reported problem includes a short reason and solution so contributors can resolve violations quickly.
🔌 Port Numbers ↑
Overview of all connectors used during development and in final packages:
| Service | Port | Command / Package | Notes |
|---|---|---|---|
| Sketchpad | 3000 |
dev js js sketchpad |
Vite dev server for Sketchpad |
| Play | 4000 |
dev play |
Vite dev server for Play |
| Docs | 4321 |
dev docs |
Astro dev server (default) |
| Storybook | 6006 |
dev js js storybook |
Storybook dev server (default) |
| Playwright | 5173 |
npm test (js) |
Test server for Playwright E2E tests |
| Engine | YYMM |
@semio/engine package |
Connector derived from release: rYY.MM-V → YYMM (e.g., r25.07-1 → 2507) |
- Automation scripts now live in TypeScript; run them with
npx tsx <script>.tsand keep shared helpers inscripts/utils.ts. - Development tickets live under
log/YEAR/MONTH/DAY/SLUG.mdwith YAML frontmatter tracking iterations (agent work sessions). - Create a ticket:
npx tsx scripts/log.ts ticket create SLUG --prompt="User prompt...". - Start an iteration (requires files):
npx tsx scripts/log.ts ticket iteration start SLUG --model=MODEL --prompt="User prompt..." --file=path.ts. - Finish an iteration (requires files, computes git line stats):
npx tsx scripts/log.ts ticket iteration finish SLUG --file=path1.ts --file=path2.ts. - Finish the ticket (aggregates files and recomputes total line stats):
npx tsx scripts/log.ts ticket finish SLUG --summary="...". - Reopen a finished ticket (removes total files/lines, sets status to open):
npx tsx scripts/log.ts ticket reopen SLUG. - Backfill missing ticket prompts:
npx tsx scripts/log.ts ticket migrate prompts. - Validation reports live in
reports/and are generated by husky pre-commit hooks in JSON format; all reports are gitignored. - The codebase report
reports/code.jsonruns thecodepolicy with tree-structured violation kinds:code:header:*(validates header region with filename, contributors, AGPL-3.0 license),code:section:*(validates region naming, content, and definition-scoped orphans outside sections, including comment and import/package blocks in Go),code:comment:*(flags inline, block, and JSDoc comments); license headers, region markers, TODOs, and[DEBUG]logs are exempt from comment enforcement. - Each code report problem includes a reason and a solution to document policy intent and remediation steps.
- Documentation is centralized in the root
README.mdandAGENTS.md; non-rootAGENTS.mdfiles and non-packageREADME.mdfiles are flagged byreports/code.jsonand deleted bynpm run fix. - Runtime Sketchpad components stay console-clean: keep only warnings/errors for real problems and gate temporary diagnostics behind
[DEBUG]strings that get removed after use.
The repository uses a split fix/analyze pipeline where preflight runs both.
Run all preflight checks across the entire monorepo:
npm run preflightRun only auto-fixes/formatters:
npm run fixRun only non-mutating checks (reports in reports/):
npm run analyzepreflight runs:
fix:hooks/code.ts --fix,hooks/prettier.ts,hooks/ruff.tsanalyze:hooks/i18n.ts,hooks/code.ts(emitsreports/code.json),hooks/typescript.ts,hooks/eslint.ts
Prettier uses .prettierignore (via hooks/prettier.ts --ignore-path, includes **/prompts.md).
test runs preflight and then nx run-many -t test. build runs test and then nx run-many -t build. publish:test and publish run build first.
All pipeline commands support skipping earlier steps:
- Skip
preflightwhen running tests:npm run test -- --skip=preflight - Skip
testwhen running a build:npm run build -- --skip=test - Skip
buildwhen runningpublish:test/publish:npm run publish -- --skip=build
To scope Nx-powered steps (e.g. test, build, ESLint) to specific bundles, pass Nx args after --nx:
npm run test -- --nx --projects=@semio/jsThe repository uses husky to automatically run preflight checks before each commit:
npm install # Husky auto-installs via prepare scriptThe pre-commit hook automatically runs npm run preflight to ensure all code meets quality standards before committing.
All monorepo commands are available in VS Code through Tasks and Launch configurations.
Formatting uses .prettierrc.json and .prettierignore via .vscode/settings.json (prettier.configPath, prettier.ignorePath).
Press Ctrl+Shift+P (or Cmd+Shift+P on macOS) → "Tasks: Run Task" and select from:
Root-level commands:
build- Build all packagestest- Run all testsfix- Run auto-fixes/formattersanalyze- Run non-mutating checkspreflight- Run all preflight checks (default build task)update- Update dependenciespublish:test- Publish to test serverspublish- Publish packagesdev- Start all dev serversdev js js storybook- Start@semio/jsStorybookdev js js sketchpad- Start@semio/jsVite Sketchpad (connector3000)
Workspace-specific commands:
build [workspace]- e.g.,build js,build engine,build vscodetest [workspace]- e.g.,test js,test engine,test vscodepreflight [workspace]- e.g.,preflight js,preflight enginedev [workspace]- e.g.,dev js,dev engine,dev play,dev docs
Press F5 or use the Run and Debug panel to launch:
Development:
dev- Start all services with Python debugger attacheddev engine/dev js/dev play/dev docs/dev vscode- Individual servicesdev js js storybook/dev js js sketchpad-@semio/jsspecialized dev entrypoints
Testing:
test- Run all teststest js/test engine/test vscode- Individual test suites
Fix / Analyze:
fix- Run auto-fixes/formattersanalyze- Run non-mutating checks
Preflight:
preflight- Run all preflight checkspreflight js/preflight engine/preflight vscode- Individual checks
Building:
build assets/build icons/build engine/build js/build docs- Individual builds
Publishing:
update/publish:test/publish- Root-level publishing commands
If you need to run individual hooks for debugging:
# Formatters
npx tsx hooks/prettier.ts
npx tsx hooks/ruff.ts
# Linters
npx tsx hooks/i18n.ts
npx tsx hooks/code.ts
npx tsx hooks/typescript.ts # Uses root tsconfig.json
npx tsx hooks/eslint.tsRequired post-change checks are npx tsx hooks/code.ts, npx tsx hooks/typescript.ts, and npx tsx hooks/eslint.ts (plus npx tsx hooks/i18n.ts when changing UI IDs/translations).
The TypeScript hook runs tsc --noEmit --project tsconfig.json. The root tsconfig.json is strict and uses moduleResolution: "bundler", explicitly includes .storybook/**/*.ts(x), and excludes temp/, js/temp/, reports/, and log/.
Most of our codebase is heavily optimized for AI agents 🤖
We pick tools based on billing model (request-based vs token-based), required context size, and whether a workflow needs MCP (e.g. Playwright) 🧰
🛠️ Uses-Cases ↑
Here some strategic advice for different uses-cases 🗺️
⚖️ Decision Making ↑
Model will always tell you that your ideas, guesses, analysis, … are great 💯
This makes it really hard to use them for decision making because they tend to just reinforce your own bias 📢
Try to formulate everything as neutral, general and unbiased as possible 🕊️
🔁 Refactoring ↑
Most refactors are too big to be done in one go and models are usually steered that if they think the problem is too big then they try to automate it with scripting 🤖
This is usually not possible and then they fail ❌
After all from a provider perspective those tasks are dangerous and hard to scale and we understand why they want the model to avoid doing it 🔥
The next problem is that when they take the wrong approach then, due to large context, they hardely remember how the original state was 🤔
For this reason, we usually create a new file which we name with the suffix*.old and this way in the prompt we can refer to the original state 📄
🐛 Bug Fixes ↑
Try to describe only how to the bug appears and not what you think caused it 😶
Experience what can be causes for bugs is increadibly valuable skill as a developer but the problem is that models are really biased the way you ask questions 🏋️
Especially when your guess is wrong then the model might have found the mistake but because of your bias it tries to take a different approach to fix it 🔀
Secondly, if the model can't find the bug then it will often try to remove functionality, add try catch blocks, add logging and other things that fastly turn your codebase into a mess 💣
Therefore, it is often a good idea that after you found the bug, reset your branch and create a new ticket where you define exactly how to fix the bug 🪛
⌨️ Tools ↑
🌐 Web-Chat ↑
For research, prompt preparation or single file-related operations (sorting, formatting, explaining, …) we use the free , Gemini or Groq, … in the browser to not waste precious tokens 🆓
The free quota is very quickly reached but resets regularly and hence we just use it for questioning or prompt preparation 💬
Good for larger experiments due to more generous free quota 🧪
💻 Editor ↑
📚 Resources:
Copilot is our default for most tickets because request-based billing makes fast iteration cheap 💳
📚 Resources:
We have the Pro plan 💳
We use Cursor as our main editor for typing code mostly with Tab ➡️
For tasks that require updated large docs that are too large to paste into the prompt, we use the agent 📚
But in general, we don't use the chat because it is way too expensive 💰
🌊 Windsurf ↑
Used for token-heavy test-driven-development workflows with MCP (especially Playwright) 🧪
⌨️ CLI ↑
⌨️ Claude Code ↑
We have the Pro plan 💳
Used for small bugs and focused fixes with strong repo context 🧠
🧾 Codex ↑
Used for simple tasks (small edits, small refactors, small doc updates) 🧩
☁️ Cloud ↑
🦑 Jules ↑
[!NOTE] Free plan includes 15 tasks per day, 3 concurrent tasks and powered by Gemini 2.5 Pro 🚀
Used on the phone when no IDE is available 📱
🔍 Agents ↑
↕️ Reorderer ↑
Used to ensure consistent order of source code, docs, …
🔁 Formatter ↑
Used to ensure consistent formatting of source code, docs, …
🤖 Models ↑
The default model for agent work is Claude Opus 4.5, with GPT-5.2 Codex as an alternative 🧠
Claude Opus 4.5 ↑
GPT-5.2 Codex ↑
🔄 CI/CD ↑
📺 Channels:
- TechWorld with Nana -
devops
All automation, CI runs, and agent workflows are controlled through the canonical root commands dev, fix, analyze, preflight, test, build, update, publish:test, and publish. Only dev is allowed to stay live for watch mode, while the remaining commands must exit so CI and agents can finish reliably. publish:test and publish always run a full build first.
The root package.json uses preflight.ts to orchestrate the command pipeline, and delegates bundle builds/tests/publishing to Nx (npx nx run-many -t <target>).
♻️ Ecosystems ↑
📺 Channels:
- FreeCodeCamp -
full-bundles - Programming with Mosh -
beginner - Fireship -
quaffable- … in 100 Seconds -
high-level
- … in 100 Seconds -
- Lex Fridman -
interviews - Amigoscode -
java - tsoding -
haskell
You might have noticed that the individual components can be closely related such as sketchpad, Grasshopper and engine but they are in totally different folders 📂
The reason for this is that the repo is not disected according content but according technology stack ✂️
This is less intuitive but more tool-friendly and everything that is easier for our tools is less pain to develop 🧑💻
🟨 JavaScript ↑
📚 Resources:
- JavaScript -
mdn - Node -
intro - TypeScript -
npm - Wasm -
mdn
js/semio- Shared TypeScript/React codebase (Sketchpad UI, components, libs).js/desktop- Electron desktop shell.js/sketchpad- Standalone Sketchpad web app shell.js/docs- Documentation site.js/play- Playground.js/vscode- VS Code extension.
cd js/semio && npm run preflight📺 Channels:
- WebDevSimplified -
beginner - Jack Herrington -
react - The Net Ninja -
everything - Fireship -
quaffable - Theo - t3.gg -
opinionated - The Primeagen -
entertainment
📺 Channels:
A .NET core for semio 🥜
net/Semio.sln- .NET solution.net/Semio.Grasshopper- Grasshopper plugin.
Warning
Rhino still runs on .NET 7.0 7️⃣ Be careful to not update packages to a higher version, that might break the compatibility 🚨
📺 Channels:
- mCoding -
advanced - Anthony writes code -
advanced- Anthony explains -
features
- Anthony explains -
- Corey Schafer -
everything - ArjanCodes -
beginner - Tech with Tim -
beginner
Currently only engine but in the future it might grow and then the .venv will be centralized, …
py/engine- Python engine (domain, serialization, APIs).
cd py/engine && npm run preflight📦 Components ↑
A component is a piece of software which is packaged independently 🏝️
🧼 Code Hygiene Hooks ↑
The code hygiene hook enforces comment, license, and region policies before changes are shared. It treats empty regions as invalid structure and removes them automatically in fix mode so region blocks stay meaningful and concise. All code must sit inside named regions; orphan definitions outside any section are reported as code:section:orphan-definition so you can relocate them as full definition blocks.
✅ Validation System ↑
semio includes a domain-pure validation system built entirely in semio.ts with zero JSON dependencies. All validation logic works with Kit objects and produces KitDiff-based fixes.
11 Validation Constraints:
- GUID Uniqueness - All GUIDs must be unique globally
- Type Name Uniqueness - Sibling types must have unique names
- Design Name Uniqueness - Sibling designs must have unique names
- Piece Name Uniqueness - Pieces in a design must have unique names
- Quality Name Uniqueness - All qualities must have unique names
- Interface Name Uniqueness - All ports must have unique names
- File Name Uniqueness - All files must have unique names
- Folder Name Uniqueness - Sibling folders must have unique names
- Connector Name Uniqueness - Connectors in a type must have unique names
- Model Name Uniqueness - Models in a type must have unique names
- Layer Path Uniqueness - Layers in a design must have unique paths
Platform Integrations:
- VS Code Extension - Kit validation with Quick Fixes, violation diagnostics with auto-refresh on save
- Sketchpad UI - In-app validation panel (planned)
- CLI - Command-line validation tool (planned)
- Backend - API validation endpoint (planned)
Usage:
import { validateSemioKit, applyKitDiff } from "@semio/js";
const result = validateSemioKit(kit);
if (result.problems.length > 0) {
const fix = result.problems[0].fixes[0];
const fixedKit = applyKitDiff(kit, fix.diff);
}See AGENTS.md for complete technical documentation.
🧾 Code Report ↑
The repository emits a machine-readable report (reports/code.json) that enforces a comment-free codebase (including multi-line and JSDoc blocks, with explicit exemptions), flags temporary [DEBUG] logs, auto-adds missing SPDX license headers in npm run fix, validates properly nested named regions, checks that js/semio files do not import outside the workspace unless they are the shared elements.tsx, flags domain-specific terminology inside those shared elements, and includes reason/solution text for each problem to make remediation explicit.
Comment detection skips comment markers inside string literals and template literal text so valid content does not raise false violations.
🎫 Ticket System ↑
Development work is tracked as tickets composed of iterations. Ticket creation does not create an iteration; iterations are explicitly started and finished, require file lists (updated, created, removed), and iteration finish derives the per-file lists and line stats from git diffs between the last iteration commit (or ticket base) and the current commit. Ticket finish aggregates all iteration files and recomputes total line stats from git against the ticket base commit.
Ticket entry points require prompt text for ticket creation and iteration start, while file arrays can be omitted at entry and still enforced by iteration rules.
Line totals only include the files declared in the ticket iterations so unrelated diffs stay out of ticket reports.
Temporary scripts, fixtures, and data stay inside the active ticket folder so work-in-progress artifacts remain scoped to the task.
?? MCP Tool Gateway ↑
The MCP server validates tool argument types and required fields before invoking the CLI so errors are surfaced at the tool boundary instead of silently proceeding. File and folder arguments are checked for path correctness so directory paths cannot be passed where files are required.
👥 Contributors ↑
Contributor activity is derived from ticket frontmatter and source file headers, so authorship and ownership stay aligned with the artifacts people actually touch. Each contributor aggregates tickets, commits, bundles, files, and line totals, and the list is ordered by ticket volume so the most active contributors surface first.
🧭 Command Tree ↑
The command browser groups actions by command families and subcommands, using the same command breakdown as the CLI so users learn one structure across tools. Search matches either command labels or group names, and matching a group keeps its full subtree visible for quick discovery.
🧩 Sections Explorer ↑
The VS Code extension adds a Sections view to the built-in Explorer that lists nested regions for the active file via the repo section list. Selecting a section navigates to its start, F2 triggers rename, drag-and-drop moves sections, and inline actions use repo commands to create child sections, rename sections, or delete them. The view refreshes on editor focus and text changes so the tree stays aligned with the current file structure. JSON files surface object keys as section entries so structured config files are navigable in the same tree.
UI borders are semantic kinds so the same component can be restyled without rewriting class lists:
border-elementis the default UI element border kind and matches the hover color.border-windowis the window border kind and matches the normal border color.
GoldenLayout stack windows render the window frame as an inset 1px stroke (overlay frame) so all four edges stay visible even when containers clip their contents.
- The base canvas, windows, panels, and temporary surfaces use different background levels.
- In a multi-window layout, exactly one window is active; its surface uses an active background tint and embedded table views inherit that surface background.
Use them with normal Tailwind border utilities like border, border-t, border-l, and divide-*.
📚 Resources:
- React -
npm - Vite -
npm - Tailwind CSS -
official - Shadcn -
official - Radix UI -
official - Lucide -
npm - Storybook -
npm - Three.js -
npm - React Three Fiber -
npm - React Three Drei -
npm - React Flow -
npm - Yjs -
npm - sql.js -
npm- Docs -
official - API -
docs - Issues -
github - Playground -
demo
- Docs -
- dnd kit -
npm - Cytoscape -
npm - Markdoc -
npm - Motion -
npm
📼 Videos:
The core which is shared in the semio JavaScript ecosystem 🥜
js/semio/sketchpad/elements.tsxprovidesTransactionProvideranduseTransaction()for UI-scoped transactions.- Sketchpad elements (
Input,Textarea,Select,Slider,Stepper,Combobox, ...) useuseTransaction()internally and do not accept atransactionprop. - Apps wrap their UI subtree with
TransactionProviderusing the appropriate transaction hook so all descendant elements participate in undo/redo consistently.
js/semio/sketchpad/elements.tsxGeometryrenders selection/hover colors even when a basecoloris provided (it is treated as the non-interactive default).- Hover and selection state for Home/Kit/Design/Type/Quality/Docs/Feedback is stored in the Sketchpad state machine; UI rows and diagram nodes dispatch hover events and visuals read from machine state.
js/semio/sketchpad/elements.tsxTableexposes row hover callbacks so apps can forward row enter/leave events into their state machine commands.js/semio/sketchpad/Design.tsxdiagram nodes usering-*(notring-inset) so hover/selection rings remain visible withAvatarFallbackbackgrounds.
- Window spacing uses the shared unit sizing system: a single unit gap between windows and a single unit margin between windows and the canvas edge.
js/semio/sketchpad/Sketchpad.tsxCanvasappliesp-single(1 unit) and window containers (HorizontalWindows/VerticalWindows) applygap-single(1 unit).- GoldenLayout window gaps use splitters sized to 1 unit and window borders are applied to the stack container via an inset 1px stroke;
Windowuseskind="layout"inside GoldenLayout to avoid nested borders. - Window chrome controls are rendered as Action UI elements and forwarded to the underlying layout system when needed.
- Window surfaces paint the only filled background surface; surrounding UI and overlays remain transparent and rely on borders/blur.
- Each app registers its supported window kinds and provides a default layout; per-app
windowLayoutis persisted as a JSON string.
js/semio/sketchpad/Kit.tsxcreate actions forports,tags,concepts, andfoldersset thekindfilter and selection to the newly created entity so the details panel opens immediately.- Default names are resolved via i18n labels:
semio.sketchpad.app.port.defaultName,semio.sketchpad.app.tag.defaultName,semio.sketchpad.app.concept.defaultName. js/semio/sketchpad/Kit.tsxdetails panel sections are registered dynamically; remove all possible section ids (including conditional variants) before adding the active one and mirror removals in the effect cleanup.js/semio/sketchpad/Kit.tsxdetails panel section content that usesuseKit()is wrapped inKitScopeProviderso read-only detail sections can resolve kit data consistently.js/semio/sketchpad/Kit.tsxread-only artifact detail fields reuse the sameidvalues as the corresponding app details (Type/Design) so i18n/tooltips stay centralized.
js/semio/sketchpad/Sketchpad.tsxexposes a singlesketchpadMachineactor that owns all Sketchpad UI state (SketchpadState+ app slices like Home/Kit/Design/Type/Quality/Tutorial).- Y.js is reserved for Kit data synchronization (per-kit
KitStoredocuments). - Sketchpad UI state is persisted locally via
localStoragekeysemio.sketchpad.state.<id>(no Y.js dependency for settings/navigation/panel sizes). - Global interaction mode is stored as
SketchpadState.deviceand controlled viauseDevice()/SET_DEVICEwith i18n IDssemio.sketchpad.settings.device.*. layoutnaming is reserved for window layout configs (GoldenLayout) and theLayoutcomponent injs/semio/sketchpad/elements.tsx.
KitStore keeps kit concepts in the yConcepts array as ConceptStore entries so snapshots expose full concept data (name, description, icon, attributes) and persistence rehydrates from that array instead of guid placeholders.
The UI uses a standardized unit-based sizing system for consistent spacing and sizing across all components. The system is derived from the --spacing CSS variable and uses Tailwind utility classes.
The UI consists of five hierarchical levels, each with its own z-index and background styling:
- Base - The foundation layer for the main canvas and background
- Window - Container level for windows within the canvas
- Panel - Floating panels and sidebars
- Overlay - Transparent layer (only affects z-index, not background)
- Temporary - Tooltips, dropdowns, modals, and transient UI
Each level (except overlay) has a background surface. Components use the LevelProvider context and useLevel() hook to access the current level, with helper functions for consistent styling:
The global Sketchpad shell is wrapped in LevelProvider level="base" so top-level chrome (Navbar/Footer) always resolves bg-base.
Panels are rendered under LevelProvider level="panel" so panel chrome and content consistently resolves bg-panel.
getLevelBgClass(level)- Returns background class (e.g.,bg-base,bg-window,bg-panel,bg-temporary)getLevelHoverClass(level)- Returns hover background class (e.g.,hover:bg-hover-base)getLevelZClass(level)- Returns z-index class (e.g.,z-base,z-window,z-panel,z-overlay,z-temporary)getLevelActiveHoverClass(level)- Returns active state hover class (e.g.,data-[state=active]:bg-hover-base)
All size constants are defined in js/semio/globals.css and derived from --spacing:
- Single: 1 unit (e.g.
gap-1) - spacing between elements and between icon and element - Tiny: 3 units (e.g.
h-tiny,w-tiny,text-tiny) - icon size in actions, action text size - Small: 5 units (e.g.
h-small,w-small) - actions, avatars, Strip items - Medium: 7 units (e.g.
h-medium,w-medium) - buttons, toggles, inputs, sliders, steppers, Footer, table rows, Strip - Large: 9 units (e.g.
h-large,w-large) - Band, Navbar - Huge: 11 units (e.g.
h-11) - height of navigation buttons at bottom of docs pages - Mega: 13 units (e.g.
w-mega) - width of toggles with actions (toggles with dropdown or action buttons) - Giga: 15 units (e.g.
w-giga) - reserved for future use
- All spacing between elements uses Tailwind unit classes (e.g.
gap-1,p-1,m-1) - Icons within actions use
h-tiny w-tinyand action labels usetext-tiny - Interactive elements (buttons, toggles, inputs) use
h-medium - Toggles with actions (dropdown or action button) use
h-medium w-mega - Bands and navbars use
h-large - Strips, footers, and table rows use
h-medium - Table body cells use
px-single py-0and center their content soh-mediumrow height stays fixed even when cells containh-mediumcontrols (toggles/inputs) - Table headers use
h-large - Large navigation elements use
h-11(huge) - Navbar panel toggles list panels in the fixed order Details, Chat, Settings across all apps
The unit system automatically adapts based on the --spacing mode (compact vs touch).
The code runs in different environments (different browsers, electron, mobile/desktop/tablet). Platform-specific functionality MUST be generalized and provided as props to Sketchpad. NEVER hardcode platform-specific behavior or APIs directly in components.
✏️ @semio/desktop ↑
📚 Resources:
🤖 @semio/assistant ↑
📚 Resources:
- Model Context Protocol -
official - OpenAI -
official - Claude -
official - Gemini -
official - Groq -
official
Currently not implemented in this repo (planned component) 🧩
📚 @semio/docs ↑
📺 Channels:
- Coding in Public -
astro
🎛️ @semio/play ↑
A playground for sketchpad 🎮
VS Code extension providing real-time violation diagnostics for semio development.
Shows policy violations as diagnostics for all supported file types (TypeScript, JavaScript, JSON, Python, C#, Go):
- Loads cached violations on file open for immediate feedback
- Re-runs
repo analyzeon file save and updates diagnostics - Quick Fix actions to apply automated fixes via
repo fix - Promotes preview editors opened from the Problems list into regular tabs for save-ready edits
Real-time validation for kit JSON files with Quick Fix code actions that apply KitDiff-based fixes.
Tree views for tickets, policies, contributors, and commands with search and filter support.
Ticket tree items expose inline close or reopen actions that apply to the clicked ticket, list commit entries derived from ticket and iteration commits, and keep hover tooltips limited to the ticket description.
🟪 @semio/net ↑
📚 Resources:
- Fluent Validation -
nuget - Refit -
nuget - QuickGraph -
nuget - Newtonsoft.Json -
nuget - UnitsNet -
nuget - Humanizer -
nuget - SVG -
nuget - GrGen.NET -
official
The core which is shared in the semio .NET ecosystem 🥜
📚 Resources:
-
Rhino -
official- Rhino Developer -
dev- Rhino Developer API -
reference - RhinoCommon API -
reference
- Rhino Developer API -
- Grasshopper -
official- Grasshopper SDK -
reference
- Grasshopper SDK -
- Forum -
forum
- Rhino Developer -
📺 Channels:
- [Nono Martínez Alonso](https://www.youtube.com/c/NonoMart%C3%ADnezAlonso)A full-blown Grasshopper Plugin that has (almost) everything 💯
Analogous to our principles for text-based code, we follow a similar logic for script-based code 🔄
💻 Optimize your definitions for rectangular space ✅
Every inch of wasted screen space, means a loss of productivity because you need longer for navigation 🖱️
It is harder to understand something far away compared to something close 🔍
I know, the triangular layout where you place the next component always vertically in the middle of the inputs looks cleaner due to the better wire display 🧹
But you waste a lot of space for nothing 💸
📛 Don't name things unless it is the output of a group or cluster ❌
We know that there are only two hard things in Computer Science: Cache invalidation and naming things 🥈
Visual programming languages solve the naming problem by using wires to overcome the neeed of names ⬆️
That is a big gain in productivity because you can focus on the logic instead of the names 🚀
Wait, but how I am supposed to understand what is happening in the code if I don't use names?
Most things in Grasshopper are visual and the green Only draw preview of selected components button on the top left is your best friend 🔍
📦 If you don't absolutely need a cluster, don't create it ❌
Clusters are a good way to make code reusable and hide complexity 🥸
But hiding complexity means a slower development speed because you have to navigate through more files 🐌
Did you know that Grasshopper behaves different inside a cluster when outside?
E.g. when you feed an empty branch into a cluster the input inside it its magically pruned and when you leave it is there again which makes debugging much harder 🐛
I don't have to tell you about open definition tabs, updating nested clusters, recompute, performance, … right?
🤏 Minimize the amount of external parameters and take as much decisions as possible ✅
Designing means making decisions 🪨
Fewer parameters makes your design more parameteric and not less 🤯
The price for a synergizing system is the loss of flexibility 🤷♂️
If you don't know the parameters in the first place, you shouldn't create the Grasshopper script in the first place 🥈
Grasshopper is an amazing tool if you know the system that you want to create but is terrible for prototyping because of its lack of abstraction ⬇️
⚙️ @semio/engine ↑
📚 Resources:
- Pydantic -
pypi - SQLAlchemy -
pypi - SQLModel -
pypi - Uvicorn -
pypi - Starlette -
pypi - FastAPI -
pypi - Graphene -
pypi - starlette-graphene3 -
pypi - Graphene Pydantic -
pypi - Graphene SQLAlchemy -
pypi - NetworkX -
pypi - Lark -
pypi - Numpy -
pypi - Pint -
pypi - pytransform3d -
pypi - Loguru -
pypi
A hidden fat-client which exposes shared functionality to other desktop uis 🤝
It takes care of:
- CRUDs (Create-Read-Update-Delete) for local kits 💾
- Client-Server communication
↔️
It offers two APIs to other clients:
- A simple REST OpenAPI 🥇
- A complex GraphQL Relay API 🥈
{} REST OpenAPI
If you go to http://127.0.0.1:2412/api/docs/ you find the Swagger UI:
Still a prototype ✏️
If you go to http://127.0.0.1:2412/graphql/ you find the GraphiQL UI:
🛍️ @semio/assets ↑
Each badge is created with shields.io with style flat-square and semio colors.
- Copy the
*.shieldsfile of an existing badge 📄 - Open and download the
*.svgfile ⬇️
- Search font on fontsource.org 🔍
- Hit
Downloadand extract zip file 📂 - Use kebaberized font name as folder name and remove everything else (such as version numbers) ➖
- Merge all types in one folder (
ttf,webfonts, …) - they won't collide due to different extensions 🗃️ - Remove all parts that repeat everywher (such as common name prefix, single weighted fonts, …) 💯
- Open favicongenerator.net 🔍
- Select
CircleasBackground Shape⏺️ - Select
AntaasFont Family📃 - Enter the
Codethat you find in the dictionary - Adjust the
Font Sizeto the largest so that the space to the side is the same as the thickness of the stroke 🖊️ - Toggle
Enable SVGon 🔳 - Hit
Generate Faviconand download the zip file toassets/icons/temp/NAME.zipwhereNAMEis the lowercase name and verb of the icon 📂 - Repeat the process for all icons 🔁
- Run
build iconsin the debugger of vscode 🔨
assets/index.ts is the shared entry point for @semio/assets. It re-exports the icon layer plus the Metabolism kit fixtures and helper constants. The kit fixtures are available as MetabolismKit, MetabolismKitDiff, MetabolismKitDiffed, MetabolismKitDiffInverted, InvalidKit, and InvalidKitValidation, while each kit entity list is exposed through MetabolismKitTypes, MetabolismKitDesigns, MetabolismKitInterfaces, MetabolismKitQualities, MetabolismKitFiles, MetabolismKitFolders, MetabolismKitAuthors, MetabolismKitTags, MetabolismKitConcepts, MetabolismKitAttributes, and the dedicated MetabolismKitNakaginCapsuleTowerDesigns.
Lookup tables MetabolismKitTypesByGuid, MetabolismKitTypesByName, MetabolismKitDesignsByGuid, MetabolismKitDesignsByName, MetabolismKitInterfacesByGuid, and MetabolismKitInterfacesByName provide direct access to every type, design, and port without filtering.
👋 Hello semio ↑
🫀 Metabolism ↑
💯 Brand ↑
✍️ Concept ↑
✅ Do ↑
- Visual is better than text 👀
- Compact ➡️ More information ➡️ Faster to understand 🚀
❌ Dont ↑
- Rounded corners ⬜
- Shadows 🌤️
- Multiple unicode directly after each other 🥇🥈🥉
🌈 Colors ↑
| Name | Hex | RGB | HSL | HSV (or HSB) | CMYK | Color |
|---|---|---|---|---|---|---|
| Primary | #FF344F | 255, 52, 79 | 352, 100, 60.2 | 352, 79.6, 100 | 0, 80, 69, 0 | Folly |
| Secondary | #00A69D | 0, 166, 157 | 176.7, 100, 32.5 | 176.7, 100, 65.1 | 100, 0, 5, 35 | Persian green |
| Tertiary | #FA9500 | 250, 149, 0 | 34.8, 100, 49 | 35.76, 1, 0.49 | 0, 40, 100, 2 | Princeton orange |
| Dark (= 0) | #001117 | |||||
| Grey 100 (= 0.1 = 1/10) | #06171C | |||||
| Dark 8-9 (= 0.1̅ = 1/9) | #07181D | |||||
| Dark-Dark-Dark-Grey (= 0.125 = 1/8) | #091A1F | |||||
| Dark 6-7 (= 0.142857 = 1/7) | #0C1C21 | |||||
| Dark-Dark-Grey (= 0.166667 = 1/6) | #112025 | |||||
| Grey 200 (= 0.2 = 1/5) | #18272A | |||||
| Dark 7-9 (= 0.2̅ = 2/9) | #1D2B2F | |||||
| Dark Grey (= 0.25 = 1/4) | #243235 | |||||
| Dark 5-7 (= 0.285714 = 2/7) | #2E3C3D | |||||
| Grey 300 (= 0.3 = 3/10) | #334041 | |||||
| Dark-Dark-Grey (= 0.3̅ = 1/3) | #3E494A | |||||
| Dark-Grey-Grey-Grey (= 0.375 = 3/8) | #4C5756 | |||||
| Grey 400 (= 0.4 = 2/5) | #555F5D | |||||
| Dark 4-7 (= 0.428571 = 3/7) | #606966 | |||||
| Dark 5-9 (= 0.4̅ = 4/9) | #666E6B | |||||
| Grey (= 0.5 = 1/2) | #7B827D | |||||
| Light 5-9 (= 0.5̅ = 5/9) | #91968F | |||||
| Light 4-7 (= 0.571429 = 4/7) | #979B94 | |||||
| Grey 600 (= 0.6 = 3/5) | #A2A59D | |||||
| Light-Grey-Grey-Grey (= 0.625 = 5/8) | #ABADA4 | |||||
| Light-Grey-Grey (= 0.6̅ = 2/3) | #B9BBB0 | |||||
| Grey 700 (= 0.7 = 7/10) | #C4C4B9 | |||||
| Light 5-7 (= 0.714286 = 5/7) | #C9C8BD | |||||
| Light Grey (= 0.75 = 3/4) | #D3D2C5 | |||||
| Light 7-9 (= 0.7̅ = 7/9) | #DAD9CB | |||||
| Grey 800 (= 0.8 = 4/5) | #DFDDD0 | |||||
| Light-Light-Grey (= 0.8̅ = 5/6) | #E6E4D5 | |||||
| Light 6-7 (= 0.857143 = 6/7) | #EBE8D9 | |||||
| Light-Light-Light-Grey (= 0.875 = 7/8) | #EEEADB | |||||
| Light 8-9 (= 0.8̅ = 8/9) | #F0ECDD | |||||
| Grey 900 (= 0.9 = 9/10) | #F1EDDE | |||||
| Light (= 1) | #F7F3E3 |
🥇 Primary ↑
Use the primary color for the most important elements of your design 🏆
We use it e.g. for:
- Highlighting interactive elements 🖱️
- Background for important elements 🟥
🥈 Secondary ↑
🥉 Tertiary ↑
⚫ Dark ↑
⚪ Light ↑
🩶 Gray ↑
Are you curious how a 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 and 11 colored gradient can come together for an invertible theme in a semantically meaningfull way? Well, here is how you achieve it with 33 colors 🤯
📄 Typography ↑
Note
Try to place notes either in the beginning or the end of a section
- Be consistent with your language ♻️
- When things are analogical use the same sentence structure for it 🔄
- One symbol after every sentance 💯
- One symbol at a time 🥇
- A symbol is preferably an emoji or otherwise unicode ⚖️
- 📝 One symbol to summarize a title
- 💡 One symbol to summarize a title description and one to think about in the end 🤔
.are forbidden ⛔- All components in
semio(sketchpad,studio, …) start with a small letter 🔡 - Did you know that
…is just one character?
Tip
In the end of a section you can give the curious reader a summarizing question to think about the consequences and a link to more resources 🤔
🔡 Typesetting ↑
- Sans serif: Anta 🖨️
- Serif: Kelly Slab ✍️
- Monospaced: Shart Tech Mono 🖥️
- Emoji: Noto Emoji ⚫
👀 Visual elements ↑
- Sharp corners 📐
- Borders □
- Basic geometric shapes ⚪
The files in this repository are licensed under the GNU Affero General Public License unless otherwise described. Most libraries, modules, extensions, objects or code herein are explicitly licensed. This is indicated in the root of the containing folder under a different license file, or in the configuration files of a bundle or in the respective file's header.
As a reference, different type of components have usually different licenses:
- software libraries: LGPLv3 or later - GNU Lesser General Public License Version 3
- applications: AGPLv3 or later - GNU Affero General Public License Version 3
- examples: MIT - The MIT License
- templates: CC0 - No Rights Reserved
- assets: CC BY-ND 4.0 - Attribution-NoDerivatives 4.0 International
If you have any questions, please don't hesitate to get in touch with us over email 📧
If you have any security vulnerabilities or concerns, please contact us over email and don't open an issue, discussion or write into our public discord server 🥷
|
Ueli Saluz 🟨 🟪 🐍 🦗 ✏️ ⚙️ 🤖 🎛️ 📚 🛍️ 💯 🦏 🐝 🦌 🐞 🫀 👋 🚀 |
KinanSarak 📚 👋 🦗 |
Christian Hödtke 🦗 |
AdrianoCelentano 🟨 |
drymuzzle 🦗 🐞 |
kaatzjo ⚙️ |
pizzadizza 🤖 |
📊 Stats
We use Goatcounter for gaining insights about our docs 📈









