Zero is not a framework. Zero is an approach to modern frontend development without the need of a framework. Technically, Zero is a set of types and functions that enables jsx to be transpiled in dom nodes.
I see modern frameworks not as technology, they are a products. Often your users don't need or even benefit from updates, but you do - the developer. With zero, you never have to update any framework, because its just the dom.
Become a framework, that can have breaking changes and or updates. Provide a npm package so you can download the code.
import{Navbar}from"../components/navbar.tsx";import{HttpClient}from"../plugins/http.ts";// Use self made dependency injectionexportdefaultasync({ $http }: {$http: HttpClient})=>{// Have dom nodes as referenceslettitle=<div>loading...</div>;lethelloWorld=<text>Hello world</text>;// Have dom nodes as configurable factoriesconstMyButton=(props: {title: string})=><button>{props.title}</button>// You dont need reactivity, just use getter/settersetInterval(()=>(helloWorld.innerText=Math.random().toString()),25);// Use modern dom api's to your advantage (replaceWith)$http.get("https://jsonplaceholder.typicode.com/todos/1").then((res)=>res.json()).then((response)=>title.replaceWith(<h1>{response.title}</h1>));return(<section><stylecomment="This style only applies to the parent node (section)">display: flex;</style><Navbar></Navbar>{title}{helloWorld}<MyButton/></section>);};Under the hood zero is just a few snippets and vite/esbuild configuration that configures the transpiling process of jsx to js. All functions return dom nodes, herefore you can use all methods available on the dom.
Runtime javascript
exportconst__createElement=(tag,props, ...children)=>{if(typeoftag==="function"){returntag(props, ...children);}if(typeoftag==="object"){throw"Cannot parse object, please use function";// element = structuredClone(tag)}constelement=document.createElement(tag);Object.entries(props||{}).forEach(([name,value])=>{if(name.startsWith("on")&&name.toLowerCase()inwindow)element.addEventListener(name.toLowerCase().substr(2),value);elseelement.setAttribute(name,value.toString());});// Todo this style feature might be a little too frameworky// It is more or less the same as styled components// https://styled-components.com/children.forEach((child)=>{if(typeofchild==="object"&&child.tagName==="STYLE"){element.style=child.innerText;}else{appendChild(element,child);}});returnelement;};constappendChild=(parent,child)=>{if(Array.isArray(child))child.forEach((nestedChild)=>appendChild(parent,nestedChild));elseparent.appendChild(child.nodeType ? child : document.createTextNode(child));};// Todoexportconst__createFragment=(props, ...children)=>{returnchildren;};Vite config
// vite.config.jsimport{defineConfig}from'vite';import{resolve}from'path';exportdefaultdefineConfig({resolve: {alias: {'~': resolve(__dirname,'src'),},},esbuild: {loader: 'tsx',// Tell vite to resolve tsx flejsxInject: `import {__createElement, __createFragment} from '~/jsx.js'`,// Tell vite to inject this functions into the main js filejsxFactory: '__createElement',// Tell vite to use this name as jsx factory function. in react its React.createElement or "h" in preact.jsxFragment: '__createFragment',// Tell vite to use this name as jsx fragment function. in react its React.createElement or "h" in preact.},});Zero provides a set of types, that enable a good developer experience. Under the hood, the types just connect jsx types with dom types. There are caveats, but in general it works fine.
// https://dev.to/ferdaber/typescript-and-jsx-part-ii---what-can-create-jsx-22h6// https://github.com/ferdaber --> Der weiss evtl ne Mengedeclare global {namespaceZero{typeWithClass<Type>={[PropertyinkeyofType]?: Type[Property];}&{class?: string;};// interface ThisTypeMightBeUseful extends HTMLElementTagNameMap { }interfaceHtmlElementextendsOmit<HTMLElement,"style">{style?: string;}// Maybe we can construct a joined type with these stuff// This example excludes style from the HTMLElementTagNameMap// type NoCart = Omit<HTMLElementTagNameMap, "style">;interfaceHtmlElementTagNameMapextendsOmit<HTMLElementTagNameMap,"style">{style?: string;}interfaceSvgElementTagNameMapextendsOmit<SVGElementTagNameMap,"style">{style?: string;}}namespaceJSX{interfaceElementextendsZero.HtmlElement{new(props: any,context?: any): Zero.WithClass<Zero.HtmlElement>;}typeElementClass=never;typeElementAttributesProperty=never;typeElementChildrenAttribute=never;// custom prop types for example <div myProp={} />typeIntrinsicAttributes={[PropertyinkeyofZero.HtmlElement]?: Zero.HtmlElement[Property];};typeIntrinsicClassAttributes={[PropertyinkeyofZero.HtmlElement]?: Zero.HtmlElement[Property];};typeSvgAny={[PropertyinkeyofZero.SvgElementTagNameMap]?: any;};typeIntrinsicElements={// SVG does not exist in[PropertyinkeyofZero.HtmlElementTagNameMap]?: Zero.WithClass<Zero.HtmlElementTagNameMap[Property]>;}&SvgAny;}}