stellis v0.1.2
stellis
A no-VDOM, JSX framework for SSR
Install
npm install --save stellisyarn add stellispnpm add stellisSetup for classic JSX
Comment pragmas (Babel, Typescript, ESBuild etc.)
Automatic runtime
/* @jsxRuntime automatic */ /* @jsxImportSource stellis */Classic runtime
/* @jsxRuntime classic */ /* @jsx h */ /* @jsxFrag Fragment */ import { h, Fragment } from 'stellis';
Typescript
Reference: https://www.typescriptlang.org/docs/handbook/jsx.html#configuring-jsx
Automatic runtime
{ "compilerOptions": { "jsx": "react-jsx", // or "react-jsxdev" "jsxImportSource": "stellis", } }Classic runtime
{ "compilerOptions": { "jsx": "react", "jsxFactory": "h", "jsxFragmentFactory": "Fragment" } }
import { h, Fragment } from 'stellis';ESBuild
Reference: https://esbuild.github.io/api/#transformation
Automatic runtime
CLI
esbuild --jsx=automatic --jsx-import-source="stellis" --jsx-devOptions
const option = { jsx: 'automatic', jsxDev: true | false, jsxImportSource: 'stellis', };
Classic runtime (as options)
CLI
esbuild --jsx=transform --jsx-factory=h --jsx-fragment=FragmentOptions
const option = { jsx: 'transform', jsxFactory: 'h', jsxFragment: 'Fragment', };
Setup for optimized JSX
Babel
Stellis uses Babel to transform your JSX and is provided in the form a plugin exported through stellis/babel.
Integrations
- Rollup (SOON)
- Vite (SOON)
- ESBuild (SOON)
Usage
Rendering JSX
import { render } from 'stellis';
const result = await render(<h1>Hello World</h1>);
console.log(result); // <h1>Hello World</h1>Stellis JSX is unlike your usual, React-like JSX:
- Stellis has no VDOM
- The babel compiler will always generate optimized templates from the JSX
- Stellis' attributes are closer to HTML
- React introduced some properties like
className,htmlForandreadOnlyto be closer to DOM than HTML, which is the opposite of Stellis, where you can writeclass,htmlandreadonly.
- React introduced some properties like
- Rendering is always async
Writing your first component
function Message({ greeting, receiver }) {
return <h1>{greeting}, {receiver}</h1>;
}
const result = await render(
<Message greeting="Hello" receiver="World" />
); // <h1>Hello World</h1>Async components
async function Profile({ id }) {
const user = await getUser(id);
return <ProfileDetails user={user} />;
} async function Profile({ id }) {
return <ProfileDetails user={await getUser(id)} />;
} Attributes
class and class:<name> directives
<h1 class="example">Hello</h1>
<h1 class={["a", condB && b]}>Array</h1>
<h1 class={{ a: true, b: condB, c: condC }}>Object</h1>
<h1 class={["a", { b: condB }, [condC && "c"]]}>Nested</h1><h1 class:example>Hello</h1>
<h1 class:a class:b={cond}>Another Example</h1>style and style:<property> directives
<h1 style={{color: "red"}}>Red Heading</h1>
<h1 style:color="red">Red Heading 2</h1>set:html
Sets the raw HTML content of the given element. Always takes priority over children.
<div set:html="<script>Hello World</script>" />Built-in Components
ErrorBoundary/<stellis:boundary>
Attempts to render children. If it receives an error, fallback is called with the received error and the result is rendered instead.
import { ErrorBoundary, render } from 'stellis';
function FailingComponent() {
throw new Error('Example');
}
const result = await render(
<ErrorBoundary
fallback={(error) => <>
<h1>Error: {error.name}</h1>
<p>Message: {error.message}</p>
</>}
>
<FailingComponent />
</ErrorBoundary>
);
console.log(result);
// Output: <h1>Error: Error</h1><p>Message: Example</p>Fragment/<stellis:fragment>
Same behavior as <></> except this allows raw HTML output with set:html
<Fragment set:html="<script>Hello World</script>" />
<stellis:fragment set:html="<script>Hello World</script>" />Comment/<stellis:comment>
Allow inserting HTML comments
<stellis:comment value="This is a comment." />
// Output: <!--This is a comment.-->Dynamic
import { Dynamic, render } from 'stellis';
function Example({ as, children }) {
return <Dynamic component={as}>{children}</Dynamic>;
}
const result = await render(
<Example as="h1">Hello World</Example>
);
console.log(result);
// Output: <h1>Hello World</h1>Context API
import { createContext, setContext, getContext, render } from 'stellis';
const message = createContext('Hello World');
function Parent({ children }) {
setContext(message, 'Bonjour World');
return children;
}
function Child() {
return <h1>{getContext(message)}</h1>; // Hello World
}
const result = await render(
<>
<Parent>
<Child />
</Parent>
<Child />
</>
);
console.log(result);
// Output
// <h1>Bonjour World</h1><h1>Hello World</h1>Stellis meta
Built-in components that renders after the markup has resolved. Both <stellis:head> and <stellis:body> has the types "pre" and "post" which defines where the children are going to be injected.
Head/<stellis:head>
<stellis:head type="pre">
<title>Hello World</title>
</stellis:head>Body/<stellis:body>
<stellis:body type="post">
<script src="./my-script.js" />
</stellis:body>Sponsors
License
MIT © lxsmnsyc