# Quickstart

## Install

```bash
npm install @glyphcss/react
```

  

```bash
npm install @glyphcss/vue
```

  

```bash
npm install glyphcss
```

## Hello cuboctahedron

```tsx
import { GlyphCamera, GlyphScene, GlyphOrbitControls, GlyphMesh, GlyphHotspot } from "@glyphcss/react";

export function App() {
  return (
    <GlyphCamera rotX={25} zoom={50}>
      <GlyphScene>
        <GlyphOrbitControls drag wheel />
        <GlyphMesh geometry="cuboctahedron">
          <GlyphHotspot id="vertex" at={[1, 0, 0]} onClick={() => alert("vertex")} />
        </GlyphMesh>
      </GlyphScene>
    </GlyphCamera>
  );
}
```

  

```vue
<template>
  <GlyphCamera :rot-x="25" :zoom="50">
    <GlyphScene>
      <GlyphOrbitControls drag wheel />
      <GlyphMesh geometry="cuboctahedron">
        <GlyphHotspot id="vertex" :at="[1, 0, 0]" @click="onClick" />
      </GlyphMesh>
    </GlyphScene>
  </GlyphCamera>
</template>

<script setup lang="ts">
import { GlyphCamera, GlyphScene, GlyphOrbitControls, GlyphMesh, GlyphHotspot } from "@glyphcss/vue";
function onClick() { alert("vertex"); }
</script>
```

  

```html
<script type="module" src="https://esm.sh/glyphcss/elements"></script>

<glyph-camera rot-x="25" zoom="50">
  <glyph-scene>
    <glyph-orbit-controls drag wheel></glyph-orbit-controls>
    <glyph-mesh geometry="cuboctahedron">
      <glyph-hotspot at="1,0,0"></glyph-hotspot>
    </glyph-mesh>
  </glyph-scene>
</glyph-camera>
```

## What you get

- A single `<pre>` rendered as ASCII glyphs — no canvas, no WebGL.
- Drag-to-orbit and scroll-to-zoom out of the box via `<GlyphOrbitControls>`.
- One absolutely-positioned `<div class="glyph-hotspot">` for each `<GlyphHotspot>`,
  re-projected through the same camera each render so it stays glued to the mesh.

## Try a Platonic solid

```tsx
import { GlyphCamera, GlyphScene, GlyphOrbitControls, GlyphMesh } from "@glyphcss/react";
import { icosahedronPolygons } from "@glyphcss/core";

const icosa = icosahedronPolygons({ center: [0, 0, 0], size: 1, color: "#44ffcc" });

export function IcosahedronDemo() {
  return (
    <GlyphCamera rotX={25} zoom={50}>
      <GlyphScene mode="solid">
        <GlyphOrbitControls />
        <GlyphMesh polygons={icosa} />
      </GlyphScene>
    </GlyphCamera>
  );
}
```

  

```vue
<template>
  <GlyphCamera :rot-x="25" :zoom="50">
    <GlyphScene mode="solid">
      <GlyphOrbitControls />
      <GlyphMesh :polygons="icosa" />
    </GlyphScene>
  </GlyphCamera>
</template>

<script setup lang="ts">
import { GlyphCamera, GlyphScene, GlyphOrbitControls, GlyphMesh } from "@glyphcss/vue";
import { icosahedronPolygons } from "@glyphcss/core";

const icosa = icosahedronPolygons({ center: [0, 0, 0], size: 1, color: "#44ffcc" });
</script>
```

  

```ts
import { createGlyphCamera, createGlyphScene } from "glyphcss";
import { icosahedronPolygons } from "@glyphcss/core";

const host = document.querySelector<HTMLElement>("#scene")!;
const camera = createGlyphCamera({ rotX: 25, zoom: 50 });
const scene = createGlyphScene(host, { camera, mode: "solid", cols: 80, rows: 24 });
scene.add(icosahedronPolygons({ center: [0, 0, 0], size: 1, color: "#44ffcc" }));
```

Next: [Core Concepts](/core-concepts) to understand what's happening under the hood.
