Convert Figma logo to code with AI

ionic-team logostencil

A toolchain for building scalable, enterprise-ready component systems on top of TypeScript and Web Component standards. Stencil components can be distributed natively to React, Angular, Vue, and traditional web developers from a single, framework-agnostic codebase.

12,489
783
12,489
276

Top Related Projects

227,213

The library for web and native user interfaces.

207,677

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core

95,657

Deliver web apps with confidence 🚀

78,194

Cybernetically enhanced web apps

36,546

⚛️ Fast 3kB React alternative with the same modern API. Components & Virtual DOM.

18,486

Lit is a simple library for building fast, lightweight web components.

Quick Overview

Stencil is a compiler for building fast, reusable UI components and Progressive Web Apps. It generates standards-based Web Components that run in any modern browser and can be used with any JavaScript framework or even without a framework.

Pros

  • Framework-agnostic: Components built with Stencil can be used in any major framework or with no framework at all
  • Performance-focused: Generates highly optimized components with a small footprint
  • TypeScript support: Built-in TypeScript support for better developer experience and type safety
  • Automatic documentation generation: Generates API documentation for components

Cons

  • Learning curve: Requires understanding of Web Components and TypeScript
  • Limited ecosystem: Smaller community and fewer third-party components compared to React or Vue
  • Build process complexity: May require additional setup for complex projects
  • Browser support: Older browsers may require polyfills for Web Components

Code Examples

  1. Creating a simple component:
import { Component, Prop, h } from '@stencil/core';

@Component({
  tag: 'my-component',
  styleUrl: 'my-component.css',
  shadow: true,
})
export class MyComponent {
  @Prop() name: string;

  render() {
    return <div>Hello, {this.name}!</div>;
  }
}
  1. Using lifecycle methods:
import { Component, State, h } from '@stencil/core';

@Component({
  tag: 'my-timer',
})
export class MyTimer {
  @State() time: number = 0;
  timer: number;

  connectedCallback() {
    this.timer = setInterval(() => this.time++, 1000);
  }

  disconnectedCallback() {
    clearInterval(this.timer);
  }

  render() {
    return <div>Time: {this.time} seconds</div>;
  }
}
  1. Handling events:
import { Component, Event, EventEmitter, h } from '@stencil/core';

@Component({
  tag: 'my-button',
})
export class MyButton {
  @Event() buttonClicked: EventEmitter<void>;

  handleClick() {
    this.buttonClicked.emit();
  }

  render() {
    return <button onClick={() => this.handleClick()}>Click me</button>;
  }
}

Getting Started

  1. Install Stencil:

    npm init stencil
    
  2. Choose a starter project (e.g., component).

  3. Navigate to the project directory and install dependencies:

    cd my-component
    npm install
    
  4. Start the development server:

    npm start
    
  5. Build for production:

    npm run build
    

Competitor Comparisons

227,213

The library for web and native user interfaces.

Pros of React

  • Larger ecosystem and community support
  • More mature and battle-tested in production environments
  • Extensive third-party libraries and tools available

Cons of React

  • Steeper learning curve for beginners
  • Requires additional libraries for state management and routing
  • Larger bundle size compared to Stencil's output

Code Comparison

React component:

import React from 'react';

const MyComponent = ({ name }) => {
  return <div>Hello, {name}!</div>;
};

export default MyComponent;

Stencil component:

import { Component, Prop, h } from '@stencil/core';

@Component({
  tag: 'my-component',
})
export class MyComponent {
  @Prop() name: string;

  render() {
    return <div>Hello, {this.name}!</div>;
  }
}

Key Differences

  • React uses a virtual DOM, while Stencil compiles to standard Web Components
  • Stencil generates smaller, more optimized bundles
  • React has a more flexible architecture, while Stencil enforces a stricter component model
  • Stencil provides built-in lazy loading and code splitting
  • React offers more control over rendering and update cycles

Use Cases

  • React: Large-scale applications, complex UIs, and projects requiring extensive customization
  • Stencil: Design systems, reusable component libraries, and performance-critical applications
207,677

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core

Pros of Vue

  • More mature ecosystem with extensive community support and resources
  • Flexible and easy to integrate into existing projects
  • Comprehensive official documentation and learning resources

Cons of Vue

  • Larger bundle size compared to Stencil
  • Potential performance overhead in complex applications
  • Less focus on web components and cross-framework compatibility

Code Comparison

Vue component:

<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello, Vue!'
    }
  }
}
</script>

Stencil component:

import { Component, h, State } from '@stencil/core';

@Component({
  tag: 'my-component'
})
export class MyComponent {
  @State() message: string = 'Hello, Stencil!';

  render() {
    return <div>{this.message}</div>;
  }
}

Key Differences

  • Vue uses a template-based approach, while Stencil uses JSX
  • Stencil focuses on generating web components, Vue is a full-fledged framework
  • Vue has a more traditional component structure, Stencil uses decorators
  • Stencil is designed for better performance and smaller bundle sizes
  • Vue offers more built-in features and directives out of the box
95,657

Deliver web apps with confidence 🚀

Pros of Angular

  • Full-featured framework with a comprehensive ecosystem
  • Powerful dependency injection system
  • Extensive CLI tools for project scaffolding and management

Cons of Angular

  • Steeper learning curve due to its complexity
  • Larger bundle size, which can impact initial load times
  • More opinionated, potentially limiting flexibility in some cases

Code Comparison

Angular component:

@Component({
  selector: 'app-hello',
  template: '<h1>Hello, {{name}}!</h1>'
})
export class HelloComponent {
  @Input() name: string;
}

Stencil component:

@Component({
  tag: 'my-hello',
  template: '<h1>Hello, {{name}}!</h1>'
})
export class MyHello {
  @Prop() name: string;
}

Key Differences

  • Angular is a full-fledged framework, while Stencil is a compiler for building web components
  • Stencil focuses on creating reusable, framework-agnostic components
  • Angular has a more extensive feature set but comes with added complexity
  • Stencil produces smaller, more performant output suitable for various frameworks

Use Cases

  • Choose Angular for large-scale applications requiring a comprehensive framework
  • Opt for Stencil when building lightweight, reusable components for multiple projects or frameworks

Community and Ecosystem

  • Angular has a larger community and more third-party libraries
  • Stencil, while growing, has a smaller but focused ecosystem centered around web components
78,194

Cybernetically enhanced web apps

Pros of Svelte

  • Smaller bundle sizes due to compile-time optimization
  • Simpler, more intuitive syntax with less boilerplate
  • Built-in state management without additional libraries

Cons of Svelte

  • Smaller ecosystem and community compared to more established frameworks
  • Limited tooling and IDE support
  • Potential performance issues with larger applications

Code Comparison

Svelte component:

<script>
  let count = 0;
  function increment() {
    count += 1;
  }
</script>

<button on:click={increment}>
  Clicks: {count}
</button>

Stencil component:

import { Component, h, State } from '@stencil/core';

@Component({
  tag: 'my-component',
})
export class MyComponent {
  @State() count: number = 0;

  increment() {
    this.count += 1;
  }

  render() {
    return (
      <button onClick={() => this.increment()}>
        Clicks: {this.count}
      </button>
    );
  }
}

Both Svelte and Stencil aim to simplify component creation, but Svelte's syntax is more concise. Stencil uses TypeScript and decorators, which may be familiar to Angular developers. Svelte's reactivity is built-in, while Stencil relies on decorators like @State for managing component state.

36,546

⚛️ Fast 3kB React alternative with the same modern API. Components & Virtual DOM.

Pros of Preact

  • Smaller bundle size, leading to faster load times
  • Closer to vanilla JavaScript, making it easier for developers familiar with JS
  • Better performance in certain scenarios due to its lightweight nature

Cons of Preact

  • Smaller ecosystem and community compared to React or Stencil
  • Less built-in features and tooling, potentially requiring more setup
  • May not be as suitable for large-scale applications as Stencil

Code Comparison

Preact component:

import { h, Component } from 'preact';

class MyComponent extends Component {
  render() {
    return <div>Hello, {this.props.name}!</div>;
  }
}

Stencil component:

import { Component, Prop, h } from '@stencil/core';

@Component({
  tag: 'my-component',
})
export class MyComponent {
  @Prop() name: string;

  render() {
    return <div>Hello, {this.name}!</div>;
  }
}

Both Preact and Stencil offer ways to create reusable components, but Stencil provides a more structured approach with decorators and built-in optimizations for web components. Preact, on the other hand, stays closer to vanilla JavaScript and React-like syntax, making it more familiar to developers coming from those backgrounds.

18,486

Lit is a simple library for building fast, lightweight web components.

Pros of Lit

  • Lighter weight and faster runtime performance
  • Simpler API with less boilerplate code
  • Better integration with existing web standards and frameworks

Cons of Lit

  • Less comprehensive tooling and build optimization
  • Smaller ecosystem and community compared to Stencil
  • Limited built-in support for server-side rendering

Code Comparison

Lit component:

import { LitElement, html } from 'lit';

class MyElement extends LitElement {
  render() {
    return html`<p>Hello, World!</p>`;
  }
}
customElements.define('my-element', MyElement);

Stencil component:

import { Component, h } from '@stencil/core';

@Component({
  tag: 'my-element',
})
export class MyElement {
  render() {
    return <p>Hello, World!</p>;
  }
}

Both Lit and Stencil are popular libraries for building web components, but they have different approaches and trade-offs. Lit focuses on simplicity and adherence to web standards, while Stencil offers a more comprehensive toolset and optimization features. The choice between them depends on project requirements, team preferences, and performance considerations.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

stencil-logo

Stencil

A compiler for generating Web Components using technologies like TypeScript and JSX, built by the Ionic team.

StencilJS is released under the MIT license. StencilJS is released under the MIT license. PRs welcome! Follow @stenciljs Official Ionic Discord

Quick Start · Documentation · Contribute · Blog
Community: Discord · Forums · Twitter

Getting Started

Start a new project by following our quick Getting Started guide. We would love to hear from you! If you have any feedback or run into issues using Stencil, please file an issue on this repository.

Examples

A Stencil component looks a lot like a class-based React component, with the addition of TypeScript decorators:

import { Component, Prop, h } from '@stencil/core';

@Component({
  tag: 'my-component',            // the name of the component's custom HTML tag
  styleUrl: 'my-component.css',   // css styles to apply to the component
  shadow: true,                   // this component uses the ShadowDOM
})
export class MyComponent {
  // The component accepts two arguments:
  @Prop() first: string;
  @Prop() last: string;

   //The following HTML is rendered when our component is used
  render() {
    return (
      <div>
        Hello, my name is {this.first} {this.last}
      </div>
    );
  }
}

The component above can be used like any other HTML element:

<my-component first="Stencil" last="JS"></my-component>

Since Stencil generates web components, they work in any major framework or with no framework at all. In many cases, Stencil can be used as a drop in replacement for traditional frontend framework, though using it as such is certainly not required.

Contributing

Thanks for your interest in contributing! Please take a moment to read up on our guidelines for contributing. Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

NPM DownloadsLast 30 Days