Skip to content

Your First Stack

In this tutorial, you’ll build an end-to-end real-time data pipeline in 15 minutes. We’ll create a “Counter” stack that tracks on-chain increment events and displays the live count in a React app.

A full-stack streaming application consisting of:

  1. A Rust Spec: Defines how to transform on-chain Solana events into a “Counter” entity.
  2. A Cloud Deployment: A managed Hyperstack instance that processes the stream.
  3. A React Frontend: A live dashboard that updates instantly as on-chain events occur.

The “Spec” is the heart of your stack. It tells Hyperstack which on-chain data to watch and how to project it into a useful state.

Terminal window
cargo new counter-spec --lib
cd counter-spec

Add hyperstack to your Cargo.toml:

[dependencies]
hyperstack = "0.1"
serde = { version = "1.0", features = ["derive"] }

Open src/lib.rs and define your projection. For this tutorial, we’ll assume a simple Solana program with a CounterAccount and an Increment instruction.

src/lib.rs
use hyperstack::{hyperstack, Stream, Strategy};
#[hyperstack(idl = "counter_idl.json")]
pub mod counter_stack {
use super::*;
#[entity]
#[derive(Stream)]
pub struct Counter {
#[map(from = "CounterAccount", field = "authority", primary_key = true)]
pub owner: String,
#[aggregate(from = "Increment", field = "amount", strategy = Sum)]
pub total_count: u64,
#[derive_from(from = "Increment", field = "__timestamp")]
pub last_updated: i64,
}
}

Hyperstack uses AST serialization. When you compile your code, it automatically generates a .hyperstack/Counter.ast.json file.

Terminal window
cargo build

Now let’s push your spec to the cloud. Hyperstack manages the infrastructure, so you don’t need to worry about scaling or WebSocket servers.

Terminal window
hs auth login

This creates a hyperstack.toml file that links your local AST to the cloud.

Terminal window
hs config init

The up command is a shortcut that pushes your AST, builds the container, and deploys it to a global cluster.

Terminal window
hs up counter-stack

Expected Output:

✔ Spec pushed (v1)
✔ Build created (id: bld_123...)
✔ Build completed
🚀 Deployed to: wss://counter-stack.stack.hypertek.app

Finally, let’s build the frontend. We’ll use the Hyperstack React SDK to subscribe to live updates.

Terminal window
npx create-react-app my-counter-app --template typescript
cd my-counter-app
npm install hyperstack-react zustand

Wrap your app in HyperstackProvider using the URL you got from the previous step.

src/index.tsx
import { HyperstackProvider } from 'hyperstack-react';
const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
<HyperstackProvider websocketUrl="wss://counter-stack.stack.hypertek.app">
<App />
</HyperstackProvider>
);

Tell the React SDK about your “Counter” entity.

src/stack.ts
import { defineStack, createListView } from 'hyperstack-react';
export interface Counter {
owner: string;
total_count: number;
last_updated: number;
}
export const CounterStack = defineStack({
name: 'counter-stack',
views: {
counters: {
list: createListView<Counter>('Counter/list'),
},
},
});

Create a component that displays the live data.

src/App.tsx
import { useHyperstack } from 'hyperstack-react';
import { CounterStack } from './stack';
export default function App() {
const stack = useHyperstack(CounterStack);
const { data: counters, isLoading } = stack.views.counters.list.use();
if (isLoading) return <div>Connecting to stream...</div>;
return (
<div>
<h1>Live Counters</h1>
{counters?.map((c) => (
<div key={c.owner} style={{ padding: '1rem', border: '1px solid #ccc' }}>
<h3>Owner: {c.owner}</h3>
<p>Count: <strong>{c.total_count}</strong></p>
<small>Last updated: {new Date(c.last_updated * 1000).toLocaleString()}</small>
</div>
))}
</div>
);
}

Ensure you ran cargo build in your Rust project. The #[hyperstack] macro generates the AST file during compilation.

  1. Check that the URL matches the output of hs up.
  2. Ensure your spec is successfully deployed by running hs deploy list.
  1. Verify that your Solana program is actually emitting the events or updating the accounts defined in your spec.
  2. Check the browser console for any subscription errors.