atellmer / dark

The lightweight and powerful UI rendering engine without dependencies and written in TypeScriptπŸ’« (Browser, Node.js, Android, iOS, Windows, Linux, macOS)
MIT License
40 stars 1 forks source link
angular components concurrent fiber framework frontend hooks jsx nativescript no-build-required nodegui performance react renderer server-side-rendering spring-animation typescript ui virtual-dom web

Dark

The lightweight and powerful UI rendering engine without dependencies and written in TypeScript
(Browser, Node.js, Android, iOS, Windows, Linux, macOS) license github release npm downloads bundle size

Features

const Greeting = component(({ name }) => <h1>Hello {name} πŸ₯°</h1>);

<Greeting name='Alice' />

Installation

from template:

npx degit github:atellmer/dark/templates/browser app
cd app
npm i
npm start

Dark vs React Fiber

Demos

Stackblitz demos

Motivation

This project was written in my free time as a hobby. I challenged myself: can I write something similar to React without third-party dependencies and alone. The biggest discovery for me: writing a rendering library is not difficult, it is difficult to write one that is fast and consumes little memory. And this is a really hard task.

Inspiration

If you liked the project, please rate it with a star ⭐, it gives me inspiration to work for the benefit of the open-source community.

Ecosystem

Package Description URL
@dark-engine/core Abstract core with main functionality Link
@dark-engine/platform-browser Renderer for browser (Single-Page apps) Link
@dark-engine/platform-server Renderer for Node.js (Multi-Page, Static-Gen and Universal apps) Link
@dark-engine/platform-native Renderer for Android, iOS (Native mobile apps) Link
@dark-engine/platform-desktop Renderer for Windows, Linux, macOS (Native desktop apps) Link
@dark-engine/web-router Isomorphic router for browser and server Link
@dark-engine/native-navigation Dark NativeScript router Link
@dark-engine/animations Spring based animations Link
@dark-engine/styled Styled components Link
@dark-engine/data Declarative queries and mutations Link

Usage

import { component, useState } from '@dark-engine/core';
import { createRoot } from '@dark-engine/platform-browser';

const App = component(() => {
  const [name, setName] = useState('Dark');

  return (
    <>
      <div>Hello {name}</div>
      <input value={name} onInput={e => setName(e.target.value)} />
    </>
  );
});

createRoot(document.getElementById('root')).render(<App />);

without JSX:

import { Text, component, useState } from '@dark-engine/core';
import { createRoot, div, input } from '@dark-engine/platform-browser';

const App = component(() => {
  const [name, setName] = useState('Dark');

  return [
    div({ slot: Text(`Hello ${name}`) }),
    input({ value: name, onInput: e => setName(e.target.value) }),
  ];
});

createRoot(document.getElementById('root')).render(App());

Benchmark

js-framework-benchmark

Based on the benchmark results (on the my machine), Dark is approximately 24% slower than the reference vanillajs implementation, yet it outperforms both React and Preact.

Lighthouse

A small application demonstrating the capabilities of Dark using SSR, rendering to stream, service-worker, offline mode, concurrent rendering, caching, suspense, router, async queries, lazy and styled components scores maximum points in Lighthouse.

Concurrent feature

Dark can split large rendering tasks automatically.

Turn this...

into this

LICENSE

MIT Β© Alex Plex