Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Cami.js is a simple yet powerful toolkit for interactive islands in web applications. No build step required.

License

NotificationsYou must be signed in to change notification settings

kennyfrc/cami.js

Repository files navigation

⚠️ Expect API changes until v1.0.0⚠️

Current version: 0.3.23.

Bundle Size: 14kb minified & gzipped.

A simple yet powerful toolkit for interactive islands in web applications. No build step required.

It has features you'd expect from a modern UI framework, such as reactive web components, async state management, streams, and cross-component state management.

Note that Cami specializes in bringing rich interactivity to your web application. As such, it's meant to be used alongside a backend framework such as FastAPI, Rails, Sinatra, or any server really that responds with HTML. Just paste in Cami's CDN link (or import the bundle) and you'll get the power of many modern UI frameworks without it taking over your workflow. Just progressively enhance your HTML with Cami web components.

<!-- The most basic example: the counter --><cami-counter></cami-counter><scriptsrc="https://unpkg.com/cami@latest/build/cami.cdn.js"></script><scripttype="module">const{ html, ReactiveElement}=cami;classCounterElementextendsReactiveElement{count=0template(){returnhtml`<button@click=${()=>this.count--}>-</button><button@click=${()=>this.count++}>+</button><div>Count:${this.count}</div>      `;}}customElements.define('cami-counter',CounterElement);</script>

Documentation |API Reference |CDN Link |Introduction

Learn By Example

Key Concepts:

ReactiveElement & HTML Tagged Template Literals

When you first create a web component, you'll need to subclassReactiveElement. This is an extension ofHTMLElement that turns all of your properties into observable properties. These properties are observed for changes, which then triggers a re-render oftemplate().

Thetemplate() method returnstemplate literals tagged with the html tag. The html tag is a function and you pass it a tagged template literal. It looks strange at first as it's not wrapped in parentheses, but it's just a function call with a special syntax for passing in a template literal.

This template literal is a special type of string that allows you to embed javascript expressions in it using normal string interpolation${}. Events are handled using@ (event listeners), such as@click,@input,@change, etc. Just prependany event with@ and you can handle it by passing a function, such as@click=${() => alert('clicked')}.

Below, we create aCounterElement that has acount property. When we mutatecount, the component will re-rendertemplate().

To use it, you'll need to create a custom element and register it withcustomElements.define. Then you can use it in your HTML file by adding the tag<counter-component></counter-component> like any other HTML tag.

<scriptsrc="https://unpkg.com/cami@latest/build/cami.cdn.js"></script><article><h1>Counter</h1><counter-component></counter-component></article><scripttype="module">const{ html, ReactiveElement}=cami;classCounterElementextendsReactiveElement{count=0template(){returnhtml`<button@click=${()=>this.count--}>-</button><button@click=${()=>this.count++}>+</button><div>Count:${this.count}</div>      `;}}customElements.define('counter-component',CounterElement);</script>

Features include:

  • Reactive Web Components: Simplifies front-end web development withReactiveElement. This is done throughObservable Properties. They are properties of aReactiveElement instance that are automatically observed for changes. When a change occurs, theReactiveElement instance is notified and can react accordingly by re-rendering the component. Observable properties support deep updates, array changes, and reactive attributes, making it easier to manage dynamic content. Lastly, this removes the boilerplate ofsignal(),setState(), orreactive() that you might find in other libraries.
  • Async State Management: Easily manage server data. Our library provides a simple API for fetching and updating data withquery andmutation. Use thequery method to fetch and cache data, with options to control how often it refreshes. Themutation method lets you update data and immediately reflect those changes in the UI, providing a smooth experience without waiting for server responses.
  • Cross-component State Management with Stores: Share state across different components with ease using a single store usingcami.store. By default, this useslocalStorage to persist state across page refreshes. This is useful for storing user preferences, authentication tokens, and other data that needs to be shared across components. This is also useful for storing data that needs to be shared across tabs.
  • Streams & Functional Reactive Programming (FRP): Handle asynchronous events gracefully withObservable Streams. They offer powerful functions likemap,filter,flatMap, anddebounce to process events in a sophisticated yet manageable way, for clean & declarative code.

Please visit ourDocumentation,API Reference,Examples, orCore Concepts to learn more.

Motivation

I wanted a minimalist javascript library that has no build steps, great debuggability, and didn't take over my front-end.

My workflow is simple: I want to start any application with normal HTML/CSS, and if there were fragments or islands that needed to be interactive (such as dashboards & calculators), I needed a powerful enough library that I could easily drop in without rewriting my whole front-end. Unfortunately, the latter is the case for the majority of javascript libraries out there.

That said, I like the idea of declarative templates, uni-directional data flow, time-travel debugging, and fine-grained reactivity. But I wanted no build steps (or at least make 'no build' the default). So I created Cami.

Who is this for?

  • Lean Teams or Solo Devs: If you're building a small to medium-sized application, I built Cami with that in mind. You can start withReactiveElement, and once you need to share state between components, you can add our store. It's a great choice for rich data tables, dashboards, calculators, and other interactive islands. If you're working with large applications with large teams, you may want to consider other frameworks.
  • Developers of Multi-Page Applications: For folks who have an existing server-rendered application, you can use Cami to add interactivity to your application.

Examples

To learn Cami by example, see ourexamples.

Dev Usage

Install Dependencies

bun install

Building

bun run build:docsbun run build:minify

How Docs are Built

JSDoc is used to build the API reference. We use Material for MkDocs for the documentation.

To make JSDoc be compatible with MkDocs, we use jsdoc2md to generate markdown files from JSDoc comments. We use then use MkDocs to build the documentation site.

Testing

We use Jasmine for testing. To run the tests, run:

bunx serve# serves the test files (it's just html)

Then openhttp://localhost:8080/test/SpecRunner.html in your browser.

Prior Art

  • Immer (immutable state)
  • Redux / Zustand (client state management)
  • React Query (server state management)
  • MobX (observable state)
  • lit-html (declarative templates)

Why "Cami"?

It's short forCamiguin, a pretty nice island.

About

Cami.js is a simple yet powerful toolkit for interactive islands in web applications. No build step required.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors3

  •  
  •  
  •  

Languages


[8]ページ先頭

©2009-2025 Movatter.jp