
Security News
Socket Releases Free Certified Patches for Critical vm2 Sandbox Escape
A critical vm2 sandbox escape can allow untrusted JavaScript to break isolation and execute commands on the host Node.js process.
@stacksjs/ts-craft
Advanced tools
Build lightning-fast desktop apps with web languages, powered by Zig.
bun add ts-craft
import { show } from '@stacksjs/ts-craft'
await show('<h1>Hello Craft!</h1>', { title: 'My App', width: 600, height: 400 })
import { createApp } from '@stacksjs/ts-craft'
const html = `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
font-family: system-ui, sans-serif;
}
</style>
</head>
<body>
<h1>⚡ Lightning Fast Desktop Apps</h1>
</body>
</html>
`
const app = createApp({
html,
window: {
title: 'My Craft App',
width: 800,
height: 600,
},
})
await app.show()
import { loadURL } from '@stacksjs/ts-craft'
// Load any website or local dev server
await loadURL('http://localhost:3000', {
title: 'My Web App',
width: 1200,
height: 800,
devTools: true,
hotReload: true,
})
createApp(config)Create a new Craft app instance.
import { createApp } from '@stacksjs/ts-craft'
const app = createApp({
html: '<h1>Hello</h1>', // HTML content
url: 'https://example.com', // Or load a URL
window: {
title: 'My App',
width: 800,
height: 600,
// ... more options
},
})
await app.show()
show(html, options)Quick helper to show a window with HTML.
import { show } from '@stacksjs/ts-craft'
await show('<h1>Hello World</h1>', {
title: 'My App',
width: 600,
height: 400,
})
loadURL(url, options)Quick helper to load a URL.
import { loadURL } from '@stacksjs/ts-craft'
await loadURL('http://localhost:3000', {
title: 'Dev Server',
width: 1200,
height: 800,
devTools: true,
})
interface WindowOptions {
title?: string // Window title
width?: number // Width in pixels (default: 800)
height?: number // Height in pixels (default: 600)
x?: number // X position
y?: number // Y position
resizable?: boolean // Can resize (default: true)
frameless?: boolean // Frameless window (default: false)
transparent?: boolean // Transparent background (default: false)
alwaysOnTop?: boolean // Always on top (default: false)
fullscreen?: boolean // Start fullscreen (default: false)
darkMode?: boolean // Enable dark mode
hotReload?: boolean // Enable hot reload (default: dev mode)
devTools?: boolean // Enable dev tools (default: dev mode)
systemTray?: boolean // Enable system tray (default: false)
hideDockIcon?: boolean // Hide dock icon (macOS menubar-only mode)
menubarOnly?: boolean // No window, tray icon only
titlebarHidden?: boolean // Hide titlebar (content extends into titlebar)
vibrancy?: string // macOS vibrancy effect
}
Craft supports menubar/system tray apps with or without a popup window.
import { createApp } from '@stacksjs/ts-craft'
const app = createApp({
html: `<h1>Pomodoro Timer</h1>`,
window: {
title: 'Timer',
width: 320,
height: 380,
systemTray: true, // Enable system tray icon
hideDockIcon: true, // Hide dock icon (menubar-only)
frameless: true,
transparent: true,
},
})
await app.show()
const app = createApp({
window: {
title: 'System Monitor',
menubarOnly: true, // No window, tray icon only
systemTray: true,
hideDockIcon: true,
},
})
await app.show()
// Update menubar title (e.g., "🍅 25:00")
window.craft.tray.setTitle('🍅 25:00')
// Set context menu
window.craft.tray.setMenu([
{ label: 'Start', action: 'start' },
{ label: 'Pause', action: 'pause' },
{ type: 'separator' },
{ label: 'Quit', action: 'quit' }
])
// Listen for menu actions
window.addEventListener('craft:tray:menu', (e) => {
switch (e.detail.action) {
case 'start': startTimer(); break
case 'pause': pauseTimer(); break
case 'quit': window.craft.app.quit(); break
}
})
Control the window from your HTML/JavaScript:
// Visibility
window.craft.window.show()
window.craft.window.hide()
window.craft.window.toggle()
window.craft.window.focus()
// State
window.craft.window.minimize()
window.craft.window.maximize()
window.craft.window.close()
window.craft.window.toggleFullscreen()
window.craft.window.center()
// Properties
window.craft.window.setTitle('New Title')
window.craft.window.setPosition(100, 100)
// Events
window.craft.window.on('focus', () => console.log('Focused'))
window.craft.window.on('blur', () => console.log('Blurred'))
Application lifecycle and system integration:
// Lifecycle
window.craft.app.quit()
window.craft.app.hide()
window.craft.app.show()
// Dock (macOS)
window.craft.app.hideDockIcon()
window.craft.app.showDockIcon()
window.craft.app.setBadge('3')
window.craft.app.bounce()
// Notifications
window.craft.app.notify({
title: 'Timer Complete',
body: 'Your focus session is done!'
})
// System info
window.craft.app.isDarkMode() // Returns true/false
window.craft.app.getLocale() // Returns 'en-US', etc.
Craft includes pre-built CSS styles for three popular sidebar designs:
import { tahoeStyles, renderTahoeSidebar, tahoeDemoData } from '@stacksjs/ts-craft'
// Use Tailwind classes
const sidebar = `<div class="${tahoeStyles.sidebar}">...</div>`
// Or render full HTML
const html = renderTahoeSidebar(tahoeDemoData)
import { arcStyles, renderArcSidebar, arcDemoData } from '@stacksjs/ts-craft'
// Gradient pills, collapsible sections
const html = renderArcSidebar(arcDemoData, false) // collapsed = false
import { orbstackStyles, renderOrbStackSidebar, orbstackDemoData } from '@stacksjs/ts-craft'
// Dark #1a1a1a theme with status indicators
const html = renderOrbStackSidebar(orbstackDemoData)
See the examples directory for more:
Run examples:
# Basic apps
bun run packages/examples-ts/hello-world.ts
bun run packages/examples-ts/todo-app.ts
# Menubar apps
bun run packages/examples-ts/menubar-timer.ts
bun run packages/examples-ts/menubar-only.ts
# Sidebar apps
bun run packages/examples-ts/file-browser.ts
bun run packages/examples-ts/arc-browser.ts
bun run packages/examples-ts/sidebar-showcase.ts
| Metric | Craft | Electron | Advantage |
|---|---|---|---|
| Startup Time | 50ms | 230ms | 4.5x faster |
| Idle Memory | 14 KB | 68 MB | 4857x less |
| Binary Size | 3 MB | 135 MB | 45x smaller |
| IPC Throughput | 2.89 µs | 2.16 ms | 748x faster |
See benchmarks for detailed performance comparisons.
# Clone the monorepo
git clone https://github.com/stacksjs/craft
cd craft
# Install dependencies
bun install
# Build the Zig core
bun run build:core
# Build the TypeScript SDK
bun run build:sdk
# Run examples
cd packages/examples-ts
bun run hello-world
We love contributions! Please see our contributing guide.
MIT © Chris Breuer
FAQs
Build desktop apps with web languages - TypeScript SDK for Craft
The npm package @stacksjs/ts-craft receives a total of 55,060 weekly downloads. As such, @stacksjs/ts-craft popularity was classified as popular.
We found that @stacksjs/ts-craft demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
A critical vm2 sandbox escape can allow untrusted JavaScript to break isolation and execute commands on the host Node.js process.

Research
Five malicious NuGet packages impersonate Chinese .NET libraries to deploy a stealer targeting browser credentials, crypto wallets, SSH keys, and local files.

Security News
pnpm 11 turns on a 1-day Minimum Release Age and blocks exotic subdeps by default, adding safeguards against fast-moving supply chain attacks.