npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tela-lang/tela

v0.3.0

Published

A declarative UI language that compiles to plain JS + CSS. Reactive components, scoped styles, zero runtime overhead.

Readme


✨ Features

  • Single File Components — state, logic, view, and styles live in one .tela file
  • Reactive by default — Proxy-based state triggers virtual DOM diffing and targeted DOM updates
  • Scoped CSS — styles compile to unique class names with zero bleed between components
  • Tiny runtime — ~10KB, zero dependencies, ships as a UMD bundle
  • Backend-agnostic — works with Spring Boot, Express, Flask, or plain static files
  • Global storestore keyword declares shared reactive state; the compiler auto-subscribes components that reference it
  • Live-reload dev servertela dev compiles, serves, and live-reloads on every .tela save
  • Zero config — no webpack, no bundler; just compile and drop a <script> tag

🚀 Quick Start

npx @tela-lang/tela init my-app
cd my-app
npm install
npx @tela-lang/tela compile-all components/ --global
open index.html

That's it. No config files. No bundler setup. Open the file in a browser and you're live.


📝 Your first component

Counter.tela

component Counter {
  state count: Number = 0

  function increment() {
    count = count + 1
  }

  function decrement() {
    count = count - 1
  }

  view {
    div {
      style {
        display: "flex"
        flex-direction: "column"
        align-items: "center"
        padding: 32px
        gap: 16px
        border-radius: 12px
        background: "#ffffff"
        box-shadow: "0 4px 24px rgba(0,0,0,0.08)"
      }

      h1 {
        content: "Count: ${count}"
        style { font-size: 48px  color: "#1a1a2e" }
      }

      div {
        style { display: "flex"  gap: 12px }

        button {
          content: "−"
          @click: decrement
          style { padding: "12px 24px"  font-size: 24px  cursor: "pointer"  border-radius: 8px  background: "#ef4444"  color: "#fff"  border: "none" }
        }

        button {
          content: "+"
          @click: increment
          style { padding: "12px 24px"  font-size: 24px  cursor: "pointer"  border-radius: 8px  background: "#22c55e"  color: "#fff"  border: "none" }
        }
      }
    }
  }
}

Compile and include:

npx @tela-lang/tela compile Counter.tela --global
<link rel="stylesheet" href="Counter.css">
<script src="https://unpkg.com/@tela-lang/tela@latest/dist/runtime.umd.js"></script>
<script src="Counter.js"></script>
<script>Tela.render(Counter, document.getElementById('app'));</script>

📦 Installation

Global install — use tela anywhere:

npm install -g @tela-lang/tela
tela compile MyApp.tela

Project devDependency — pin to a version:

npm install --save-dev @tela-lang/tela
npx tela compile MyApp.tela

No install — run directly with npx:

npx @tela-lang/tela compile MyApp.tela

🔧 CLI Reference

| Command | Description | |---|---| | tela init [name] | Scaffold a new project with a starter component | | tela compile <file.tela> | Compile a single component to .js + .css | | tela compile-all <dir> | Compile every .tela file in a directory | | tela dev [dir] | Start a live-reload dev server; watches .tela files and recompiles on every save |

Options

| Flag | Description | |---|---| | --global | Expose the component on window (required for plain <script> use) | | --port <n> | Port for tela dev (default: 3000) | | --root <dir> | Directory to serve with tela dev (default: current directory) |


🌐 Runtime CDN

unpkg:

<script src="https://unpkg.com/@tela-lang/tela@latest/dist/runtime.umd.js"></script>

jsDelivr:

<script src="https://cdn.jsdelivr.net/npm/@tela-lang/tela@latest/dist/runtime.umd.js"></script>

Mount a compiled component onto any DOM node:

Tela.render(MyComponent, document.getElementById('app'));

🏗️ Language Overview

import Header from "./Header.tela"

component UserDashboard {
  // ── State ────────────────────────────────────────────
  state users:   Array   = []
  state loading: Boolean = false
  state query:   String  = ""

  // ── Props ────────────────────────────────────────────
  prop title: String

  // ── Lifecycle ────────────────────────────────────────
  onMount {
    fetchUsers()
  }

  // ── Functions ────────────────────────────────────────
  async function fetchUsers() {
    loading = true
    response = await fetch("/api/users")
    users    = await response.json()
    loading  = false
  }

  function deleteUser(id) {
    fetchUsers()
  }

  // ── View ─────────────────────────────────────────────
  view {
    div {
      // Render a child component
      Header { title: title }

      // Two-way binding on an input
      input { bind value: query  placeholder: "Search..." }

      if (loading) {
        p { content: "Loading..." }
      } else {
        div {
          for (user in users) {
            div {
              style { display: "flex"  justify-content: "space-between"  padding: 8px }
              span { content: "${user.name}" }
              button {
                content: "Delete"
                @click: deleteUser(user.id)
              }
            }
          }
        }
      }
    }
  }
}

Core syntax at a glance

| Syntax | Purpose | |---|---| | state name: Type = value | Reactive local state | | prop name: Type | Input from parent | | computed name = expr | Derived value, auto-updates | | route path: String | Reactive URL variable for client-side routing; add a second route params: Object to capture named URL segments (e.g. /users/:idparams.id) | | store Name { field: Type = value } | Shared reactive state across components | | enum Name { A B C } | Compile-time constant set | | model Name { field: Type } | Data-shape factory | | onMount / onUpdate / onDestroy { } | Lifecycle hooks | | async function name() { } | Async function with await | | emit eventName(value) | Fire a custom event to the parent | | bind value: stateVar | Two-way input binding | | @click: fn | Event handler | | if (cond) { } else { } | Conditional rendering | | for (item in list) { } | List rendering | | switch (expr) { case v: ... } | Switch/case in logic and view | | while (cond) { } | While loop | | try { } catch (e) { } | Error handling | | content: "Hello ${name}" | Text with interpolation | | style { prop: value } | Scoped styles (static → CSS, dynamic → inline) |

Full language reference: SPEC.md · Docs site

State vs Store

Tela has two reactive primitives. Knowing which to use is the most important decision in any Tela component.

state — private to one component, lives and dies with it.

component Toggle {
  state open: Boolean = false      // only Toggle cares about this

  view {
    button { content: "Toggle" @click: open = !open }
    if (open) { p { content: "Visible" } }
  }
}

store — shared across all components that reference it, persists for the app's lifetime.

store AuthStore {
  user: Object = null
}

component NavBar {
  view {
    span { content: "Hello, ${AuthStore.user?.name}" }  // re-renders on user change
  }
}

component ProfilePage {
  view {
    p { content: "${AuthStore.user?.email}" }           // same store, same update
  }
}

Rule of thumb:

  • UI-only data (loading flag, open/close, form input) → state
  • Data two or more components share (current user, cart, settings) → store

See State and Stores in SPEC.md for the full reference.


☕ Spring Boot Integration

Tela integrates cleanly with any JVM backend. The compiler runs as a Maven plugin step during generate-resources — no extra tooling required.

pom.xml — auto-compile before the build:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>3.1.0</version>
  <executions>
    <execution>
      <id>compile-tela</id>
      <phase>generate-resources</phase>
      <goals><goal>exec</goal></goals>
      <configuration>
        <executable>npx</executable>
        <arguments>
          <argument>@tela-lang/tela</argument>
          <argument>compile-all</argument>
          <argument>${project.basedir}/src/main/resources/static/components</argument>
          <argument>--global</argument>
        </arguments>
      </configuration>
    </execution>
  </executions>
</plugin>

index.html (Thymeleaf template):

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="/components/App.css">
</head>
<body>
  <div id="app"></div>
  <script src="https://unpkg.com/@tela-lang/tela@latest/dist/runtime.umd.js"></script>
  <script src="/components/App.js"></script>
  <script>Tela.render(App, document.getElementById('app'));</script>
</body>
</html>

Run mvn spring-boot:run and Maven will compile all .tela files automatically before starting the server.


🌍 Live Demo

Spring PetClinic → Tela — a fully functional CRUD app with Owners, Pets, Vets, and Visits, built with Tela + Spring Boot + H2. Clone it, run mvn spring-boot:run, and see a complete multi-component Tela app in production form.


🏗 Architecture

Tela uses a Virtual DOM with component-level re-rendering. Here is the full picture:

| Layer | What happens | |-------|-------------| | Compiler | .tela source → ComponentDef object (plain JS + CSS). No runtime template evaluation. | | Reactive state | Tela.reactive() wraps component state in a Proxy. Any state write immediately calls instance.update(). | | Virtual DOM | Each update() call re-runs the component's render function, producing a new vnode tree. | | Diffing | _patchChildren / _patchNode diff old vs new vnodes, touching only the DOM nodes that actually changed. | | Keyed lists | Children with a key: attribute use map-based reconciliation — DOM nodes are reused by key, not by index. | | Global store | Tela.store() is a named, shared Proxy. Writes batch subscriber notifications via a microtask, so multiple store mutations in one tick produce a single re-render pass across all subscribing components. | | No-op guard | Both reactive() and store() skip re-renders when the new value === the old value. |

Granularity: re-renders are per-component, not per-property. When any piece of state inside a component changes, that component's subtree is re-diffed. Child components are reused by identity (cursor-based); only props differences are patched through.

This is the same model as React/Preact/Vue, deliberately chosen for predictability and debuggability over more aggressive compile-time optimisations.


🤝 Contributing

git clone https://github.com/tela-lang/tela.git
cd tela
npm install
npm test

Bug reports, feature requests, and pull requests are all welcome. Open an issue to discuss larger changes before submitting a PR.


🙏 Acknowledgements

Tela draws inspiration from the best ideas in modern frontend tooling:

  • Svelte — the "compile away the framework" philosophy
  • Vue.js — single-file components and template syntax design
  • React — virtual DOM diffing and component model
  • Angular — declarative template syntax and two-way binding

The Spring PetClinic demo application (© Spring team, Apache 2.0) inspired the example app in examples/petclinic-tela/.


📄 License

MIT © tela-lang