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

tawt

v0.0.7

Published

A lightweight library for building web user interfaces with a fluent, object-oriented API.

Readme

TAWT (TypeScript Abstract Window Toolkit)

A modern, lightweight, Swing-inspired library for building web UIs with a fluent, object-oriented API.

TAWT brings the structure and elegance of component-based development to the DOM, wrapped in TypeScript's type safety. Build interfaces with classes instead of templates and methods instead of CSS files.

[!WARNING] This project is currently under active development.
If you'd like to contribute or learn more, contact us at [email protected].


✨ Features

  • Object-Oriented: Build UIs with classes (TawtButton, TawtPanel, TawtLabel)
  • Fluent API: Chain methods continuously (.width(100).height(50).onClick(...))
  • Type-Safe CSS: Fully typed properties with enums (no string typos!)
  • Reusable Styles: Define TawtCSSClass once, apply everywhere
  • Compile-Time CSS: Styles are injected into the DOM automatically when classes are instantiated
  • Zero Dependencies: Lightweight and native (jQuery removed)

📦 Installation

npm install tawt

� Running the Example

This repository includes a complete example application in the example/ folder demonstrating all TAWT features.

To run it:

  1. Clone this repository
  2. Open index.html in your browser, or
  3. Run the dev server:
    npm run dev

The example showcases:

  • Login forms with validation
  • Dynamic tables and grids
  • Image galleries
  • Reusable CSS classes
  • Flexbox layouts

�🏗️ Core Concepts

TawtApplication

The entry point for your application. Manages the root container and mounts to the DOM.

import { TawtApplication, TawtPanel } from 'tawt';

const app = new TawtApplication();
const mainPanel = new TawtPanel();

app.add(mainPanel);
app.mount(); // Attaches to document.body

TawtElement

Base class for all components. Provides fluent methods for styling, events, and DOM manipulation.

import { TawtLabel, CssColors } from 'tawt';

const label = new TawtLabel('Hello World')
    .setColor(CssColors.BLUE)
    .setFontSize(24)
    .setFontWeight('bold')
    .setPadding(10);

🧩 Components

TawtPanel

A container <div> with built-in flexbox helpers.

import { TawtPanel, CssFlexDirection, CssJustify, CssAlign } from 'tawt';

const card = new TawtPanel()
    .setFlex(CssFlexDirection.COLUMN, CssJustify.CENTER, CssAlign.CENTER)
    .setGap(20)
    .setPadding(30)
    .setBackground('#f5f5f5')
    .setBorderRadius(8);

TawtButton

An interactive button with click handlers.

import { TawtButton, CssColors, CssCursor } from 'tawt';

const btn = new TawtButton('Click Me', () => alert('Clicked!'))
    .setPadding(12)
    .setBackground(CssColors.BLUE)
    .setColor(CssColors.WHITE)
    .setBorderRadius(4)
    .setCursor(CssCursor.POINTER);

TawtLabel

A text label (<span> by default).

import { TawtLabel, CssFontWeight } from 'tawt';

const title = new TawtLabel('Welcome')
    .setFontSize(32)
    .setFontWeight(CssFontWeight.BOLD)
    .setColor('#333');

TawtTextField

An input field (<input type="text">).

import { TawtTextField } from 'tawt';

const emailInput = new TawtTextField()
    .setPlaceholder('Enter your email')
    .setAttribute('type', 'email')
    .setPadding(10)
    .setBorder('1px solid #ccc')
    .setBorderRadius(4);

// Get value
const email = emailInput.getValue();

TawtForm

A semantic <form> with submit handling.

import { TawtForm, TawtFormLabel, TawtTextField, TawtButton } from 'tawt';

const form = new TawtForm();

const usernameLabel = new TawtFormLabel('Username:').setFor('username-input');
const usernameField = new TawtTextField(undefined, undefined, 'username-input');

const submitBtn = new TawtButton('Submit');

form.addComponent(usernameLabel)
    .addField(usernameField)
    .addComponent(submitBtn)
    .onSubmit(() => {
        console.log('Username:', usernameField.getValue());
    });

TawtList

Ordered (<ol>) or unordered (<ul>) lists.

import { TawtList, TawtLabel } from 'tawt';

// Unordered list
const ul = new TawtList(false); // false = <ul>
ul.push('Item 1');
ul.push('Item 2');
ul.push(new TawtLabel('Rich Item').setColor('blue'));

// Ordered list
const ol = new TawtList(true); // true = <ol>
ol.push('Step 1');
ol.push('Step 2');

TawtImage

An <img> element with fluent sizing.

import { TawtImage } from 'tawt';

const logo = new TawtImage('https://example.com/logo.png')
    .setWidth(200)
    .setHeight(100)
    .setBorderRadius(8);

TawtImageFolder

Manage multiple images from a base URL.

import { TawtImageFolder } from 'tawt';

const icons = new TawtImageFolder('https://img.icons8.com/ios/50', [
    '000000/typescript.png',
    '000000/javascript.png',
]);

const tsIcon = icons.get('000000/typescript.png');
tsIcon.setWidth(40).setHeight(40);

// Or use index access (Proxy-based)
// @ts-ignore
const jsIcon = icons[1];

TawtGrid & TawtTable

Grid and table layouts (see src/components/grid and src/components/table for details).

import { TawtGrid } from 'tawt';

const grid = new TawtGrid();
const row = grid.addRow();

row.addColumn().setWeight(2).setBackground('#FF6B6B'); // 2/3 width
row.addColumn().setWeight(1).setBackground('#4ECDC4'); // 1/3 width

🌐 HTTP Client

TAWT includes a built-in HTTP client with a fluent API, using native fetch for maximum performance and zero dependencies.

Quick Start

import { TawtHttp } from 'tawt';

// Simple GET request
const response = await TawtHttp.get<User>('https://api.example.com/users/1');
console.log(response.data);

// POST request
const newUser = await TawtHttp.post<User>('https://api.example.com/users', {
    name: 'John Doe',
    email: '[email protected]',
});

Fluent Configuration

import { TawtHttp } from 'tawt';

const api = new TawtHttp()
    .baseUrl('https://api.example.com')
    .bearer('your-token-here')
    .header('X-Custom-Header', 'value')
    .timeout(5000); // 5 seconds

// All requests use the configured base URL and headers
const users = await api.get<User[]>('/users');
const user = await api.post<User>('/users', { name: 'Jane' });

HTTP Methods

// GET
const data = await api.get<T>('/endpoint');

// POST
const created = await api.post<T>('/endpoint', { data });

// PUT
const updated = await api.put<T>('/endpoint/1', { data });

// PATCH
const patched = await api.patch<T>('/endpoint/1', { partial });

// DELETE
const deleted = await api.delete<T>('/endpoint/1');

Authentication

// Bearer token
api.bearer('your-jwt-token');

// Basic auth
api.basic('username', 'password');

// Custom headers
api.header('Authorization', 'Custom scheme');

Error Handling

import { TawtHttp, TawtHttpError } from 'tawt';

try {
    const data = await TawtHttp.get('/api/users/1');
} catch (error) {
    if (error instanceof TawtHttpError) {
        console.log(error.status); // 404
        console.log(error.statusText); // "Not Found"
        console.log(error.url); // Full URL
        console.log(error.response); // Response body

        // Helper methods
        if (error.isClientError()) {
            /* 4xx */
        }
        if (error.isServerError()) {
            /* 5xx */
        }
        if (error.isNetworkError()) {
            /* Network failure */
        }
    }
}

Response Object

const response = await api.get<User>('/users/1');

response.data; // Typed response data
response.status; // 200
response.statusText; // "OK"
response.ok; // true
response.headers; // Headers object

// Helper methods
response.isSuccess(); // true for 2xx
response.isError(); // true for 4xx/5xx
response.getHeader('Content-Type');
response.hasHeader('X-Custom');

🎨 CSS Styling

Compile-Time CSS Loading

TAWT automatically injects CSS into the DOM when you instantiate TawtCSSClass or TawtCSSId. You don't need to manually manage stylesheets.

import { TawtCSSClass, CssColors } from 'tawt';

// This creates a .card class and injects it into <style> tag
const cardStyle = new TawtCSSClass('card');
cardStyle
    .backgroundColor(CssColors.WHITE)
    .padding(20)
    .borderRadius(12)
    .boxShadow('0 2px 10px rgba(0,0,0,0.1)');

// Apply to components
const panel = new TawtPanel();
panel.applyCSSClass(cardStyle);

Fluent CSS API

All CSS properties are available as fluent methods on TawtCSSClass, TawtCSSId, and TawtElement.

Single Property

import { TawtCSSClass, CssMeasure } from 'tawt';

const style = new TawtCSSClass('example');
style.width(100, CssMeasure.PERCENT);
style.height(50, CssMeasure.VH);
style.margin(10, 20, 10, 20); // top, right, bottom, left (defaults to px)

Method Chaining

const btnStyle = new TawtCSSClass('primary-btn')
    .backgroundColor('#007bff')
    .color('white')
    .padding(12, 24, 12, 24)
    .borderRadius(6)
    .cursor('pointer')
    .fontWeight('bold')
    .fontSize(16);

Flexbox Shorthand

import { TawtCSSClass, CssFlexDirection, CssJustify, CssAlign } from 'tawt';

const containerStyle = new TawtCSSClass('flex-container');
containerStyle.flex(
    CssFlexDirection.ROW,
    CssJustify.SPACE_BETWEEN,
    CssAlign.CENTER
);

TawtCSSClass vs TawtCSSId

  • TawtCSSClass: Reusable style (compiles to .classname)
  • TawtCSSId: Unique style (compiles to #idname)
import { TawtCSSClass, TawtCSSId } from 'tawt';

// Reusable class
const buttonClass = new TawtCSSClass('btn');
buttonClass.padding(10).borderRadius(4);

// Unique ID
const headerId = new TawtCSSId('main-header');
headerId.fontSize(32).fontWeight('bold');

// Apply
const btn1 = new TawtButton('Button 1');
btn1.applyCSSClass(buttonClass);

const header = new TawtLabel('Header');
header.applyCSSId(headerId);

Inline Styles vs Classes

You can mix inline styles (via TawtElement methods) with classes:

const panel = new TawtPanel();
panel.applyCSSClass(cardStyle); // Apply class
panel.setBackground('red'); // Override with inline style

Note: Inline styles have higher specificity than classes.


🚀 Complete Example

import {
    TawtApplication,
    TawtPanel,
    TawtLabel,
    TawtButton,
    TawtTextField,
    TawtForm,
    TawtFormLabel,
    TawtCSSClass,
    CssColors,
    CssFlexDirection,
    CssJustify,
    CssAlign,
    CssCursor,
    CssFontWeight,
    CssMeasure,
} from 'tawt';

// 1. Create Application
const app = new TawtApplication();

// 2. Define Reusable Styles
const cardStyle = new TawtCSSClass('card')
    .backgroundColor(CssColors.WHITE)
    .padding(20)
    .borderRadius(12)
    .boxShadow('0 2px 10px rgba(0,0,0,0.05)');

const inputStyle = new TawtCSSClass('input')
    .padding(10)
    .border('1px solid #ddd')
    .borderRadius(6)
    .width(100, CssMeasure.PERCENT);

// 3. Build UI
const container = new TawtPanel()
    .setFlex(CssFlexDirection.COLUMN, CssJustify.CENTER, CssAlign.CENTER)
    .setGap(30)
    .setPadding(40)
    .setBackground('#f0f2f5')
    .setWidth(100, CssMeasure.VW)
    .setMinHeight(100, CssMeasure.VH);

const title = new TawtLabel('Login Form')
    .setFontSize(24)
    .setFontWeight(CssFontWeight.BOLD)
    .setColor('#333');

const form = new TawtForm().applyCSSClass(cardStyle).setWidth('350px');

const emailLabel = new TawtFormLabel('Email:').setFor('email-input');
const emailField = new TawtTextField(
    undefined,
    inputStyle,
    'email-input'
).setPlaceholder('[email protected]');

const passwordLabel = new TawtFormLabel('Password:').setFor('password-input');
const passwordField = new TawtTextField(undefined, inputStyle, 'password-input')
    .setAttribute('type', 'password')
    .setPlaceholder('••••••••');

const submitBtn = new TawtButton('Login')
    .setPadding(12)
    .setBackground(CssColors.BLUE)
    .setColor(CssColors.WHITE)
    .setBorderRadius(6)
    .setCursor(CssCursor.POINTER);

form.addComponent(emailLabel)
    .addField(emailField)
    .addComponent(passwordLabel)
    .addField(passwordField)
    .addComponent(submitBtn)
    .onSubmit(() => {
        alert(`Email: ${emailField.getValue()}`);
    });

container.add(title).add(form);
app.add(container);

// 4. Mount
app.mount();

📚 API Reference

Core

  • TawtApplication - Application entry point
  • TawtElement - Base class for all components

Components

  • TawtPanel - Container with flexbox
  • TawtButton - Interactive button
  • TawtLabel - Text label
  • TawtTextField - Input field
  • TawtForm - Form with submit handling
  • TawtFormLabel - Label for form fields
  • TawtList - Ordered/unordered lists
  • TawtImage - Image element
  • TawtImageFolder - Image collection manager
  • TawtGrid - Grid layout system
  • TawtTable - Table layout

CSS

  • TawtCSSClass - Reusable CSS class
  • TawtCSSId - Unique CSS ID
  • CssProperties - CSS property constants
  • CssColors - Color constants
  • CssMeasure - Unit constants (PX, EM, REM, PERCENT, VW, VH, etc.)
  • Enums: CssDisplay, CssPosition, CssFlexDirection, CssJustify, CssAlign, CssCursor, etc.

🤝 Contributing

Contributions are welcome! Please submit a Pull Request.

📄 License

MIT