Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5f02314
add hyperapp skeleton to templates
jurij-jukic Oct 10, 2025
bfc0a22
Format Rust code using rustfmt
github-actions[bot] Oct 10, 2025
8babfa7
template
jurij-jukic Oct 10, 2025
8556e3b
Merge remote-tracking branch 'origin/j/template-hyperapp' into j/temp…
jurij-jukic Oct 10, 2025
77c513f
add resources
jurij-jukic Oct 10, 2025
01129a8
rename hyperapp-skeleton to hyperapp
jurij-jukic Oct 10, 2025
e684a9f
remove pkg/ui and add to gitignore
jurij-jukic Oct 15, 2025
b8fdf40
remove garbage from example-apps/id/id
jurij-jukic Oct 15, 2025
6292efb
rename back from hyperapp to hyperapp-skeleton
jurij-jukic Oct 15, 2025
097c3d4
remove machine generated api folder
jurij-jukic Oct 15, 2025
c8ed6bb
fix icon
jurij-jukic Oct 15, 2025
08af650
remove obsolete comments.
jurij-jukic Oct 15, 2025
1a61992
remove api.ts and wire backend calls correctly
jurij-jukic Oct 21, 2025
fdc9304
wit_world fix
jurij-jukic Oct 21, 2025
afcbb0f
remove useless request_body args
jurij-jukic Oct 21, 2025
61d5dd7
remove file explorer
jurij-jukic Oct 21, 2025
a969490
update file explorer
jurij-jukic Oct 21, 2025
03ca3c7
gitignore cleanup
jurij-jukic Oct 21, 2025
01289dc
remove pkg/ui from file explorer
jurij-jukic Oct 21, 2025
6206ce7
clean up cargo tomls in hyperapp skeleton
jurij-jukic Oct 22, 2025
65597a2
remove types/skeleton.ts
jurij-jukic Oct 22, 2025
3a0ba89
remove CHANGES_MADE.md
jurij-jukic Oct 22, 2025
f10ac75
remove expand-sign-old.txt
jurij-jukic Oct 22, 2025
9b15386
remove caller utils from file explorer example
jurij-jukic Oct 22, 2025
f459a67
Revert "remove types/skeleton.ts"
jurij-jukic Oct 22, 2025
5bc7535
remove api stuff from types/skeleton.ts and some readme updates
jurij-jukic Oct 22, 2025
12bb808
update readme re file explorer api
jurij-jukic Oct 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,286 changes: 1,438 additions & 848 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1106,7 +1106,7 @@ async fn make_app(current_dir: &std::ffi::OsString) -> Result<Command> {
.short('t')
.long("template")
.help("Template to create")
.value_parser(["blank", "chat", "echo", "fibonacci", "file-transfer"])
.value_parser(["blank", "chat", "echo", "fibonacci", "file-transfer", "hyperapp-skeleton"])
.default_value("chat")
)
.arg(Arg::new("UI")
Expand Down
5 changes: 4 additions & 1 deletion src/new/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub enum Template {
Echo,
Fibonacci,
FileTransfer,
HyperappSkeleton,
}

impl Language {
Expand All @@ -44,6 +45,7 @@ impl Template {
Template::Echo => "echo",
Template::Fibonacci => "fibonacci",
Template::FileTransfer => "file-transfer",
Template::HyperappSkeleton => "hyperapp-skeleton",
}
.to_string()
}
Expand All @@ -68,7 +70,8 @@ impl From<&String> for Template {
"echo" => Template::Echo,
"fibonacci" => Template::Fibonacci,
"file-transfer" => Template::FileTransfer,
_ => panic!("kit: template must be 'blank', 'chat', 'echo', or 'fibonacci'; not '{s}'"),
"hyperapp-skeleton" => Template::HyperappSkeleton,
_ => panic!("kit: template must be 'blank', 'chat', 'echo', 'fibonacci', or 'hyperapp-skeleton'; not '{s}'"),
}
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/new/templates/rust/ui/hyperapp-skeleton/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[profile.release]
lto = true
opt-level = "s"
panic = "abort"

[workspace]
members = [
"skeleton-app",
"target/hyperapp-skeleton-caller-util?",
]
resolver = "2"
249 changes: 249 additions & 0 deletions src/new/templates/rust/ui/hyperapp-skeleton/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
# Hyperware Skeleton App

A minimal, well-commented skeleton application for the Hyperware platform using the Hyperapp framework.
This skeleton provides a starting point for building Hyperware applications with a React/TypeScript frontend and Rust backend.

Either prompt your favorite LLM directly with instructions on how to build your app or add them to `instructions.md`!

Recommended usage:
- Create a skeleton repo using a kit template:
```bash
kit new foo --template hyperapp-skeleton --ui
cd foo
```
Comment thread
nick1udwig marked this conversation as resolved.
- Write a detailed document describing what you want your app to do.
Save this in `instructions.md`.
- Prompt your LLM agent (i.e. Claude Code) with something like:
```
## GOAL

<One-sentence description of app here>

## Instructions

Read the README.md and follow the Instructions > Create an implementation plan
```

- After creating an implementation plan, clear your LLM agent's context and then prompt it again with something like:

```
## GOAL

<One-sentence description of app here>

## Instructions

Read the README.md and follow the Instructions > Implement the plan
```

The rest of this document is aimed at *LLMs* not *humans*.

## Quick Start

### Prerequisites

- Hyperware development environment (`kit` command)
- Rust toolchain
- Node.js and npm

### Building

Always build with
```bash
kit build --hyperapp
```

## Project Structure

```
hyperapp-skeleton/
├── Cargo.toml # Workspace configuration
├── metadata.json # App metadata
├── skeleton-app/ # Main Rust process
│ ├── Cargo.toml # Process dependencies
│ └── src/
│ ├── lib.rs # Main app logic (well-commented)
│ └── icon # App icon file
├── ui/ # Frontend application
│ ├── package.json # Node dependencies
│ ├── index.html # Entry point (includes /our.js)
│ ├── vite.config.ts # Build configuration
│ └── src/
│ ├── App.tsx # Main React component
│ ├── store/ # Zustand state management
│ ├── types/ # TypeScript type definitions
│ └── utils/ # API utilities
├── api/ # Generated WIT files (after build)
└── pkg/ # The final build product, including manifest.json, scripts.json and built package output
```

## Key Concepts

### 1. The Hyperprocess Macro

The `#[hyperprocess]` macro is the core of the Hyperapp framework. It provides:
- Async/await support without tokio
- Automatic WIT generation
- State persistence
- HTTP/WebSocket endpoint configuration

### 2. Required Patterns

#### HTTP Endpoints
ALL HTTP endpoints MUST be tagged with `#[http]`:
```rust
#[http]
async fn my_endpoint(&self) -> String {
// Implementation
}
```

#### Frontend API Calls
Parameters must be sent as tuples for multi-parameter methods:
```typescript
// Single parameter
{ "MethodName": value }

// Multiple parameters
{ "MethodName": [param1, param2] }
```

#### The /our.js Script
MUST be included in index.html:
```html
<script src="/our.js"></script>
```

### 3. State Persistence

Your app's state is automatically persisted based on the `save_config` option:
- `OnDiff`: Save when state changes (strongly recommended)
- `Never`: No automatic saves
- `EveryMessage`: Save after each message (safest; slowest)
- `EveeyNMessage(u64)`: Save every N messages received
- `EveeyNSeconds(u64)`: Save every N seconds

## Customization Guide

### 1. Modify App State

Edit `AppState` in `skeleton-app/src/lib.rs`:
```rust
#[derive(Default, Serialize, Deserialize)]
pub struct AppState {
// Add your fields here
my_data: Vec<MyType>,
}
```

### 2. Add HTTP Endpoints

For UI interaction:
```rust
#[http]
async fn my_method(&mut self) -> Result<String, String> {
// Parse request, update state, return response
}
```

### 3. Add Capabilities

Add system permissions in `pkg/manifest.json`:
```json
"request_capabilities": [
"homepage:homepage:sys",
"http-server:distro:sys",
"vfs:distro:sys" // Add as needed
]
```

These are required to message other local processes.
They can also be granted so other local processes can message us.
There is also a `request_networking` field that must be true to send messages over the network p2p.

### 4. Update Frontend

1. Add types in `ui/src/types/skeleton.ts`
2. Update store in `ui/src/store/skeleton.ts`
3. Modify UI in `ui/src/App.tsx`

### 5. Rename as appropriate

Change names throughout from `hyperapp-skeleton` (and variants) as appropriate if user describes app name.

## Common Issues and Solutions

### "Failed to deserialize HTTP request"
- Check parameter format (tuple vs object)

### "Node not connected"
- Verify `/our.js` is included in index.html
- Check that the app is running in Hyperware environment

### WIT Generation Errors
- Use simple types or return JSON strings
- No HashMap (use Vec<(K,V)>)
- No fixed arrays (use Vec<T>)
- Add #[derive(PartialEq)] to structs

### Import Errors
- Don't add `hyperware_process_lib` to Cargo.toml
- Use imports from `hyperprocess_macro`

## Testing Your App

1. Deploy app to a Hyperware node (after building, if requested):
```bash
kit start-packages
```
2. Your app will be automatically installed and available at `http://localhost:8080`
3. Check the Hyperware homepage for your app icon

## Instructions

### Create an implementation plan

Carefully read the prompt; look carefully at `instructions.md` (if it exists) and in the resources/ directory.
In particular, note the example applications `resources/example-apps/sign/`, `resources/example-apps/id/`, and `resources/example-apps/file-explorer`. Note that `file-explorer` example contains an `api`, which is generated by the compiler, and not human or LLM written.
`sign` and `id` demonstrate local messaging.
`file-explorer` demonstrates VFS interactions.

Expand the prompt and/or `instructions.md` into a detailed implementation plan.
The implementor will be starting from this existing template that exists at `skeleton-app/` and `ui/`.

Note in particular that bindings for the UI will be generated when the app is built with `kit build --hyperapp`.
As such, first design and implement the backend; the interface will be generated from the backend; finally design and implement the frontend to consume the interface.
Subsequent changes to the interface must follow this pattern as well: start in backend, generate interface, finish in frontend

Do NOT create the API.
The API is machine generated.
You create types that end up in the API by defining and using them in functions in the Rust backend "hyperapp"

Do NOT write code: just create a detailed `IMPLEMENTATION_PLAN.md` that will be used by the implementor.
The implementor will have access to `resources/` but will be working from `IMPLEMENTATION_PLAN.md`, so include all relevant context in the PLAN.
You can refer the implementor to `resources/` but do not assume the implementor has read them unless you refer them there.

### Implement the plan

Look carefully at `IMPLEMENTATION_PLAN.md` and in the `resources/` directory, if relevant.
In particular, note the example applications `resources/example-apps/sign/`, `resources/example-apps/id/`, and `resources/example-apps/file-explorer`.
Use them if useful.

Work from the existing template that exists at `skeleton-app/` and `ui/`.

Note in particular that bindings for the UI will be generated when the app is built with `kit build --hyperapp`.
As such, first design and implement the backend; the interface will be generated from the backend; finally design and implement the frontend to consume the interface.
Subsequent changes to the interface must follow this pattern as well: start in backend, generate interface, finish in frontend

Do NOT create the API.
The API is machine generated.
You create types that end up in the API by defining and using them in functions in the Rust backend "hyperapp"

Do not worry about serialization/deserialization when using `send` and `send_rmp` functions for p2p communication.
Notice that this all happens within those functions: just take the rust types as args and return rust types as return values.

If you create a GUI for the app you MUST use target/ui/caller-utils.ts for HTTP requests to the backend.
Do NOT edit this file: it is machine generated.
Do NOT do `fetch` or other HTTP requests manually to the backend: use the functions in this machine generated interface.

Implement the application described in the `IMPLEMENTATION_PLAN.md`.
18 changes: 18 additions & 0 deletions src/new/templates/rust/ui/hyperapp-skeleton/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "SkeletonApp",
"description": "A minimal skeleton app for the Hyperware platform using the Hyperapp framework - demonstrates basic state management and HTTP endpoints",
"image": "",
"properties": {
"package_name": "skeleton-app",
"current_version": "0.1.0",
"publisher": "skeleton.os",
"mirrors": [],
"code_hashes": {
"0.1.0": ""
},
"wit_version": 1,
"dependencies": []
},
"external_url": "",
"animation_url": ""
}
19 changes: 19 additions & 0 deletions src/new/templates/rust/ui/hyperapp-skeleton/pkg/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[
{
"process_name": "skeleton-app",
"process_wasm_path": "/skeleton-app.wasm",
"on_exit": "Restart",
"request_networking": false,
"request_capabilities": [
"homepage:homepage:sys",
"http-server:distro:sys",
"vfs:distro:sys"
],
"grant_capabilities": [
"homepage:homepage:sys",
"http-server:distro:sys",
"vfs:distro:sys"
],
"public": false
}
]
Loading