---
title: "Workflow"
description: "The end-to-end process of building and deploying an Arete data pipeline."
editUrl: true
head: []
template: "doc"
sidebar: {"order":1,"hidden":false,"attrs":{}}
pagefind: true
draft: false
---

Building a stack follows a straightforward four-step workflow: define your data model in Rust, compile to build the stack, deploy to Arete Cloud, and connect from your application.

---

## Step 1: Write Your Stack Definition

A stack definition is a Rust module that maps structure from the IDL into a rich, queryable state ready to consume in your application layer. Using Arete's expressive DSL, you define **entities**, field mappings, aggregations, computed fields, relationships, and more — all in declarative Rust syntax.

```rust
use arete::{arete, Stream};

#[arete(idl = "my_program.json")]
pub mod ore_stack {
    #[entity]
    #[derive(Stream)]
    pub struct OreRound {
        #[map(RoundState::round_id, primary_key)]
        pub round_id: u64,

        #[map(RoundState::motherlode)]
        pub motherlode: u64,

        #[map(RoundState::difficulty)]
        pub difficulty: u64,
    }
}
```

The Rust code is purely declarative—you're describing **what** data you want, not **how** to fetch it. Arete handles all the account parsing, event processing, and state management.

:::note
In practice, field paths use fully qualified names with the generated SDK module: e.g., `ore_sdk::accounts::RoundState::round_id`. The module name (`ore_sdk`) is derived from the IDL's program metadata. The example above is simplified for clarity.
:::

→ [Stack Definitions](/building-stacks/stack-definitions) — Learn the full DSL syntax

---

## Step 2: Build the Stack

When you compile your Rust project, Arete macros transform your definition into a portable JSON specification. This is the compiled representation of your data pipeline.

```bash
cargo build
```

After building, you'll find the generated specification in `.arete/`:

```
my-stack/
├── src/lib.rs
├── Cargo.toml
└── .arete/
    └── OreStack.stack.json    # Generated stack specification
```

The `.stack.json` file contains everything Arete needs to execute your pipeline: all entities, field mappings, aggregation logic, key resolution rules, and more. A single stack file can contain multiple entities.

---

## Step 3: Deploy with the CLI

The Arete CLI (`a4`) handles deployment to Arete Cloud. A single command pushes your stack specification, builds the execution environment, and deploys to a global edge network.

:::caution[Closed Beta]
Arete is currently in closed beta. You'll need an API key to deploy. [Contact us on X](https://x.com/usearete) to request access.
:::

```bash
# Initialize project config (creates arete.toml)
a4 init

# Deploy your stack
a4 up
```

On success, you'll receive a WebSocket URL:

```
✔ Stack pushed (v1)
✔ Build completed
🚀 Deployed to: wss://ore.stack.arete.run
```

→ [CLI Reference](/cli/commands) — Full command documentation

---

## Step 4: Generate SDK and Connect

Once deployed, generate a typed SDK for your stack:

```bash
a4 sdk create typescript ore
```

```bash
a4 sdk create rust ore
```

This creates a package containing the stack definition that tells the Arete client how to interact with your feed, including all entities and their views. Import it in your application:

```tsx
import { AreteProvider, useArete } from "arete-react";
import { ORE_STREAM_STACK } from "arete-stacks/ore"; // Generated in Step 4

// Wrap your app
<AreteProvider>
  <App />
</AreteProvider>;

// In your component
const stack = useArete(ORE_STREAM_STACK);
const { data: rounds } = stack.views.OreRound.list.use();
```

```typescript
import { Arete } from "arete-typescript";
import { ORE_STREAM_STACK } from "arete-stacks/ore"; // Generated in Step 4

const a4 = await Arete.connect(ORE_STREAM_STACK);

for await (const round of a4.views.OreRound.list.use()) {
  console.log("Round updated:", round);
}
```

```rust
use a4_sdk::prelude::*;
use ore_stack::{OreStack, OreRound};  // Generated in Step 4

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Connect to your deployed stack
    let a4 = Arete::<OreStack>::connect().await?;

    // Stream updates via typed views
    let mut stream = a4.views.ore_round.latest().listen();

    while let Some(round) = stream.next().await {
        println!("Round #{:?}: motherlode={:?}",
            round.id.round_id, round.state.motherlode);
    }

    Ok(())
}
```

Share the generated SDK with your team or publish it — anyone with the SDK can connect to your stack's feed (assuming they're authorized).

→ [Your First Stack](/building-stacks/your-first-stack) — Complete tutorial with working code

---

## Next Steps

| Goal                                | Page                                                          |
| ----------------------------------- | ------------------------------------------------------------- |
| Understand the DSL in depth         | [Stack Definitions](/building-stacks/stack-definitions)       |
| Set up your development environment | [Installation](/building-stacks/installation)                 |
| Build a complete example            | [Your First Stack](/building-stacks/your-first-stack)         |
| Learn all available macros          | [Macro Reference](/building-stacks/rust-dsl/macros)           |
| Master aggregation strategies       | [Population Strategies](/building-stacks/rust-dsl/strategies) |
