aster.UI / Docs
Aster products
Showcase ↗

Aster UI / Guides

Get started with Aster UI

Run a complete project grid, inspect the code, and see where the data model takes responsibility. If you are evaluating the library, start with why Aster UI.

This example uses plain JavaScript and custom elements. The browser runs a local OData service in WebAssembly; no backend or account is needed to try it here.

Try the working example

Sort by a column heading or filter a column. The grid sends those query changes through its data context to the OData service.

Open the example on its own · Explore a connected grid and form

Run it locally

You need Git and Bun. The repository includes the prebuilt WebAssembly mock; rebuilding the server engine is not part of this introduction.

git clone https://github.com/getaster/aster-ui.git
cd aster-ui
bun install
bun run site
bun scripts/serve-static.ts dist-local/showcase --strict

Open http://localhost:4174/playground/first-grid.html. The built site is static; use an HTTP server rather than opening HTML through a file: URL, because the example fetches modules, metadata and WebAssembly.

The standalone distribution lives in dist-local/lib/. You can also copy that directory and the two example files into your own static site, preserving their relative paths. See installation and distribution for the files and TypeScript dependencies.

The HTML shell

A theme supplies the visual tokens. The elements stylesheet supplies the controls. Importing the library module registers the custom elements.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Aster UI — project grid</title>
  <link rel="stylesheet" href="../lib/themes/lamplight.css">
  <link rel="stylesheet" href="../lib/aster-ui.css">
  <style>
    body { margin: 0; padding: 16px; background: var(--aster-page); color: var(--aster-text); font: 14px/1.5 system-ui; }
    h1 { margin: 0 0 12px; font-size: 17px; }
  </style>
</head>
<body>
  <h1>Projects</h1>
  <div id="out" aria-live="polite">Loading the local OData service…</div>
  <script>try{const s=localStorage.getItem('aster-docs-scheme')||'system';document.documentElement.dataset.scheme=s==='system'?(matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light'):s}catch{}</script>
  <script type="module" src="./first-grid.js"></script>
</body>
</html>

Connect data and render the grid

The first section starts a local service with metadata and seed records. DataContext.connect() reads the metadata and creates the shared data context.

The grid names an entity set and a view. The view describes columns, sorting and filtering; the collection handles loading records for that query. CSS gives the virtualized grid a bounded height.

import { DataContext, html, render } from "../lib/aster-ui.js";
import { createMockService } from "../lib/aster-ui-mock.js";

const out = document.querySelector("#out");
try {
  // The local OData engine lets this example run without a backend.
  const json = async name => {
    const response = await fetch(`../lib/demo/${name}.json`);
    if (!response.ok) throw new Error(`Could not load ${name}`);
    return response.json();
  };
  const mock = await createMockService({
    metadata: await json("metadata"),
    data: await json("data"),
    wasm: new URL("../lib/odata_mock.wasm", import.meta.url),
  });
  const ctx = await DataContext.connect(mock.transport);

  render(html`
    <aster-grid
      .ctx=${ctx}
      .set=${"Projects"}
      .label=${"Projects"}
      .view=${{
        columns: [
          { field: "name" },
          { field: "state" },
          { field: "health" },
        ],
        sort: [{ field: "name" }],
        filters: {},
        frozen: 0,
      }}
      style="height: 300px"
    ></aster-grid>
  `, out);
} catch (error) {
  out.setAttribute("role", "alert");
  out.textContent = `The example could not load: ${error instanceof Error ? error.message : String(error)}. Reload to try again.`;
}

The html template’s dot syntax binds JavaScript properties: .ctx=${ctx} passes an object to the element. It does not serialize that object into an HTML attribute. Import html and the reactive helpers from Aster so the controls and your application use the same runtime.

What this example establishes

The small fixture demonstrates the contract. For larger results, collection paging and row virtualization use the same API. This example does not demonstrate save conflicts or cross-view editing; the connected views how-to introduces the edit model.

Connect your own service

Replace the mock setup with a fetch transport pointing to your OData service root:

import { DataContext, fetchTransport } from "../lib/aster-ui.js";

const ctx = await DataContext.connect(
  fetchTransport("https://your-service.example/odata/")
);

Keep the rendering code, change Projects and its fields to match your metadata, and configure authentication and CORS for your deployment. The service must support the operations you enable. Metadata annotations drive field types, labels, validation and declared capabilities; see the shared data model.

Continue building

Follow these guides in order to build on the running grid:

  1. Understand the shared data model: context, collections, selection and ownership.
  2. Connect a grid and form: use that model to keep selection, drafts and saved records in sync.
  3. Compose a workspace: connect reusable controls, actions and lazy views in JavaScript or YAML.

For specific controls and appearance: