tiny, fast and declarative custom elements library (but not only custom elements)
Last updated a year ago by eavichay .
MIT · Repository · Bugs · Original npm · Tarball · package.json
$ cnpm install ottavino 
SYNC missed versions from official npm registry.


The piccolo /ˈpɪkəloʊ/ (Italian pronunciation: [ˈpikkolo]; Italian for "small", but named ottavino in Italy)

Tiny, Fast and Declarative User Interface Development

Using native custom elements API (but not only)

Build Status

As simple as it gets.

See the docs

import { component } from 'ottavino'

  tag: 'tiny-moji',
  template: '<span>{{this.moodIcon}}</span>',
  shadow: true, // optional shadow DOM
  properties: {
    moodIcon: '????'
  attributes: {
    mood: function(newValue /*, oldValue, domElement */) {
      this.moodIcon = newValue === 'sad' ? '????' : '????'
<tiny-moji mood="sad"></tiny-moji>

IIFE Version (no es-modules)

<script src="/path/to/ottavino/index.nomodule.js"></script>
  // here you go

Footprint (KBGzipped) ~1.5

1534 bytes in commit hash 8c90491


component(options: ComponentDescriptor<T?>) => ComponentProxy<T>


  • tag? When creating a custom element, this will be the DOM tag name.
  • mount? When you want to "upgrade" a legacy element on the DOM (like a <div>) and make it behave just like it was a custom element. It can be a queryselector to be executed on the document or a reference to an element instance
    • If no tag nor mount are used (or both used) - expect dragons.
  • template: string (or reference for an existing HTML template element for reuse)
  • properties? key-value properties that are reflected from the DOM element into the component handler ("proxy")
  • attributes? key-value of functions handling attribute changes. Functions receives the new and old values and a reference to the DOM element. this will refer to the handler
  • init? Initialization function during component construction. The passed argument is the DOM reference
  • this? Your (optional) component handler. Anything can go here. From within the template, and usage of this would reach this object. If none defined, it will generate a default component proxy
  • shadow? opt in for shadow DOM
  • closed? opt in for closed mode shadow DOM
  • connectedCallback? linked with the DOM connectedCallback
  • disconnectedCallback? linked with the DOM disconnectedCallback

Under the hood

<button onclick="{{this.counter++}}">Count UP!</button>
<button onclick="{{this.counter = 0}}">Reset</button>
<button onclick="{{this.hereBeDragons()}}DONT PUSH BUTTON</button>

Anything evaluated between mustache-braces will be executed within the component's context. Every execution can reach this (the component logic) and component as a reference to the DOM element. The component-handler is a component-proxy object that reflects anything to the actual DOM element and vice versa. The proxy is reachable from the DOM via proxy property name. Event handlers (any attribute that starts with "on...") also can use event as an argument passed into the expression.


Try mounting your awesome component (with shadow DOM) to the document body instead of using a custom element. In your template, don't use slots. Embed it in another webpage. Fun :unicorn:

Contribution / Roadmap

This project attempts to create the simplest developer experience while using the lastest and greatest features the borwser can provide. Next in the list:

  • "directives" (custom attributes that executes... anything),
  • Lifecycle global hooks
  • Plugins
  • Suggest your idea


Current Tags

  • 0.2.4                                ...           latest (a year ago)

9 Versions

  • 0.2.4                                ...           a year ago
  • 0.2.3                                ...           a year ago
  • 0.2.2                                ...           a year ago
  • 0.2.1                                ...           a year ago
  • 0.2.0                                ...           a year ago
  • 0.1.4                                ...           a year ago
  • 0.1.3                                ...           a year ago
  • 0.1.2                                ...           a year ago
  • 0.1.0                                ...           a year ago
Maintainers (1)
Today 0
This Week 0
This Month 0
Last Day 0
Last Week 0
Last Month 9
Dependencies (0)
Dev Dependencies (15)
Dependents (0)

Copyright 2014 - 2016 © |