Skip to content

host:net

The host:net module provides HTTP networking capabilities with capability-based access control.

Capabilities

Network access must be declared in manifest.app.toml:

[capabilities.net]
fetch = ["https://api.example.com/*", "https://cdn.example.com/*"]

Glob patterns for URL matching:

  • * - matches any characters except /
  • ** - matches any characters including /

HTTP Fetch

fetch(url, options?)

Fetch a URL and return response as text:

import { fetch } from "host:net";
const response = await fetch("https://api.example.com/data");
console.log(response.status); // 200
console.log(response.ok); // true
console.log(response.body); // Response body as string
console.log(response.headers); // { "content-type": "application/json" }

Options:

OptionTypeDefaultDescription
methodstring"GET"HTTP method
headersRecord<string, string>{}Request headers
bodystring-Request body
timeout_msnumber30000Timeout in milliseconds

Returns:

interface FetchResponse {
status: number;
statusText: string;
headers: Record<string, string>;
body: string;
url: string;
ok: boolean; // true if status 200-299
}

fetchBytes(url, options?)

Fetch a URL and return response as raw bytes:

import { fetchBytes } from "host:net";
const response = await fetchBytes("https://example.com/image.png");
const imageData = response.body; // Uint8Array

Returns:

interface FetchBytesResponse {
status: number;
statusText: string;
headers: Record<string, string>;
body: Uint8Array;
url: string;
ok: boolean;
}

fetchJson(url, options?)

Fetch a URL and parse response as JSON:

import { fetchJson } from "host:net";
interface User {
id: number;
name: string;
email: string;
}
const user = await fetchJson<User>("https://api.example.com/users/1");
console.log(user.name);

postJson(url, data, options?)

POST JSON data to a URL:

import { postJson } from "host:net";
const response = await postJson("https://api.example.com/users", {
name: "John Doe",
email: "john@example.com"
});
console.log(response.status); // 201

Request Examples

GET Request

const response = await fetch("https://api.example.com/items");
const items = JSON.parse(response.body);

POST Request

const response = await fetch("https://api.example.com/items", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ name: "New Item" })
});

With Authentication

const response = await fetch("https://api.example.com/protected", {
headers: {
"Authorization": "Bearer your-token-here"
}
});

With Timeout

const response = await fetch("https://slow-api.example.com/data", {
timeout_ms: 60000 // 60 seconds
});

Error Handling

import { fetch } from "host:net";
try {
const response = await fetch("https://api.example.com/data");
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = JSON.parse(response.body);
} catch (error) {
if (error.message.includes("permission")) {
console.error("URL not allowed - check capabilities");
} else if (error.message.includes("timeout")) {
console.error("Request timed out");
} else {
console.error("Network error:", error);
}
}

Complete Example

import { fetchJson, postJson } from "host:net";
import { notify } from "host:sys";
interface WeatherData {
temperature: number;
description: string;
humidity: number;
}
async function getWeather(city: string): Promise<WeatherData> {
try {
const data = await fetchJson<WeatherData>(
`https://api.weather.com/v1/current?city=${encodeURIComponent(city)}`
);
return data;
} catch (error) {
await notify("Weather Error", `Failed to fetch weather: ${error.message}`);
throw error;
}
}
async function reportAnalytics(event: string, data: unknown): Promise<void> {
try {
await postJson("https://analytics.example.com/events", {
event,
data,
timestamp: Date.now()
});
} catch (error) {
// Silent fail for analytics
console.warn("Analytics failed:", error);
}
}