Skip to content

dannyYassine/vanille

Repository files navigation

logo.png

A minimalistic web component framework

Using native browser features to maximum performance with a few exceptions


Dependencies Library Version

Minified size Downloads Dependencies

Dependencies


Features

  • Web components as first class citizens
  • Templating with JSX
  • Reactive rendering with signals
  • Pass objects to custom element attributes
  • No virtual DOM

logo.png

Installation

yarn add @vanille/core

Prerequisites

vite.config.ts

Using vite, please specify the esbuild options:

  esbuild: {
    jsxFactory: 'h',
    jsxFragment: 'Fragment',
  }

tsconfig.json

To use decorators, enable experimentalDecorators:

    "experimentalDecorators": true

No dependencies

All features are in-house implementations to maximize native functionality, with a few exceptions (check out below!)


Extending web components for native performance

import { View } from '@vanille/core';

export class App extends View {}

Fast templating web components with in-house JSX

export class App extends View {
  render() {
    return (
      <div>
        <span>JSX!</span>
      </div>
    );
  }
}

Signals

export class App extends View {
  render() {
    const name = state('your name');
    const computedName = computed(() => name.get());

    return (
      <div>
        <span>{name}</span>
        <span>{computedName}</span>
      </div>
    );
  }
}

Simple routing

<v-route path="/">
  Home
</v-route>
<v-route path="/dashboard">
  Dashboard
</v-route>
<v-route path="/users/:id">
  User with id
</v-route>

Pass objects in web component attributes

const user = { name: 'vanille' };

<v-app user="user"></v-app>;

export class App extends View {
  render() {
    return (
      <p>{this.props.user.name}</p>
    )
  }
}

Query the DOM with refs to update elements

export class App extends View {
  setBindings() {
    this.refs.name.textContent = newValue;
  }

  render() {
    return (
      <div>
        <span ref="name">JSX!</span>
      </div>
    );
  }
}

Declarative testing with JSX

import { mount } from './test-utils';
// load the component
import './test-utils/Test';

test('can render from jsx', () => {
  const $shadow = mount(<v-test />) <---- JSX!

  const $el = $shadow.querySelector('[data-id="test"');

  expect($el).toBeTruthy();
});