Runtime Philosophy
Happen embodies simplicity not only in its design but in its relationship with the underlying runtime environment. Unlike conventional frameworks that build abstraction layers over runtime capabilities, Happen takes a fundamentally different approach:
Happen is simply a coordination layer for events. The runtime belongs to your code.
This approach has profound implications for how you build systems with Happen.
Direct Runtime Access
With Happen, there are no framework-specific abstractions standing between your code and the runtime:
// A Happen node handling file operations
fileNode.on('save-document', async event => {
const { path, content } = event.payload;
try {
// Direct use of runtime capabilities
// No "Happen way" to do this - just use the runtime
await Bun.write(path, content);
// Return success result
return {
status: 'success',
path
};
} catch (error) {
// Return error result
return {
status: 'error',
reason: error.message
};
}
});
This example demonstrates a crucial aspect of Happen's philosophy: the framework doesn't try to abstract, wrap, or "improve" the runtime's capabilities. Your event handlers are simply JavaScript functions with full, direct access to whatever runtime they're executing in.
The Invisible Framework
Happen is designed to be virtually invisible from a runtime perspective:
// Creating a web server node
httpNode.on('start-server', event => {
const { port } = event.payload;
// Direct use of Bun's HTTP server capabilities
const server = Bun.serve({
port,
fetch(request) {
// Convert HTTP requests to events
const requestEvent = {
type: 'http-request',
payload: {
url: request.url,
method: request.method,
headers: Object.fromEntries(request.headers.entries()),
body: request.body
}
};
// Process through Happen's event system
const responseEvent = httpNode.processSync(requestEvent);
// Convert response event back to HTTP
return new Response(
responseEvent.payload.body,
{
status: responseEvent.payload.status,
headers: responseEvent.payload.headers
}
);
}
});
// Store server instance for later management
httpNode.server = server;
return { status: 'started', port };
});
In this example, the node creates and manages a web server using the runtime's native capabilities. Happen simply provides the event-based coordination layer, not the HTTP functionality itself.
"Glue with Superpowers"
This runtime philosophy exemplifies Happen's role as "glue with superpowers":
It's Just Glue: Happen connects different pieces of functionality without dictating how that functionality is implemented
Your Code, Your Runtime: Your event handlers have complete freedom to use the runtime however they need
No Hidden Magic: There's no framework-specific way to access runtime features - you use them directly
No Learning Curve: If you know how to use the runtime, you already know how to use it with Happen
The Benefits of Runtime Transparency
This direct relationship between your code and the runtime offers several key advantages:
1. Zero Overhead
Since Happen doesn't abstract the runtime, there's no performance penalty for accessing runtime capabilities:
// No performance penalty for runtime access
databaseNode.on('query-users', async event => {
const { filter } = event.payload;
// Direct database query using runtime capabilities
// No layers of abstraction adding overhead
const statement = db.prepare(`
SELECT * FROM users
WHERE name LIKE ?
`);
const users = statement.all(`%${filter}%`);
return { users };
});
2. Full Runtime Capabilities
You have access to everything the runtime offers, not just what the framework developers thought to expose:
// Using advanced runtime features
processingNode.on('process-image', async event => {
const { imagePath, options } = event.payload;
// Access to cutting-edge runtime features
// as soon as they're available in the runtime
const imageData = await Bun.file(imagePath).arrayBuffer();
const processed = await ImageProcessor.process(imageData, options);
await Bun.write(`${imagePath}.processed`, processed);
return { status: 'completed', outputPath: `${imagePath}.processed` };
});
3. Runtime Evolution
As the runtime evolves with new capabilities, they're immediately available without waiting for framework updates:
// Immediate access to new runtime features
node.on('use-new-feature', event => {
// When the runtime adds new capabilities,
// you can use them immediately without framework updates
const result = Bun.newCapability(event.payload);
return { result };
});
4. Ecosystem Compatibility
Your Happen code works seamlessly with the broader ecosystem for your runtime:
// Seamless integration with ecosystem libraries
analyticsNode.on('analyze-data', async event => {
const { dataset } = event.payload;
// Use any ecosystem library directly
// No need for framework-specific adapters or wrappers
const analysis = await performAnalysis(dataset);
return { results: analysis };
});
// Helper function using ecosystem libraries
async function performAnalysis(dataset) {
// Direct use of ecosystem libraries
// No "Happen way" to integrate libraries
const results = await someAnalyticsLibrary.process(dataset);
return results;
}
Consistent Philosophy Across Environments
This runtime philosophy remains consistent whether you're using Bun, Node.js, Deno, or browsers:
// The same approach works across different runtimes
function createFileNode(id) {
const node = createNode(id);
// Handler implementation uses runtime-appropriate APIs
// but the Happen code remains the same
node.on('read-file', async event => {
const { path } = event.payload;
try {
// In Bun
const content = await Bun.file(path).text();
// In Node.js
// const content = await fs.promises.readFile(path, 'utf8');
// In Deno
// const content = await Deno.readTextFile(path);
// In browser
// const response = await fetch(path);
// const content = await response.text();
return { content };
} catch (error) {
return { error: error.message };
}
});
return node;
}
While the specific API calls differ between environments, Happen's relationship with the runtime remains the same: it simply provides event coordination while giving your code direct access to the runtime.
The Power of Stepping Back
By stepping back and focusing solely on event coordination, Happen achieves something rare in frameworks: it gets out of your way. The framework doesn't try to be the center of your application or dictate how you should use the runtime. It simply provides the minimal structure needed for nodes to communicate through events, then lets your code take center stage.
This approach creates a unique developer experience:
Low Cognitive Load: There's no need to learn framework-specific ways to access runtime features
Maximum Flexibility: Your code can use the runtime however it needs without framework constraints
Future-Proof: As runtimes evolve, your code can immediately leverage new capabilities
True Simplicity: The framework does one thing well (event coordination) and leaves the rest to your code
Happen's runtime philosophy embodies its commitment to simplicity. By focusing solely on event coordination and giving your code direct access to the runtime, Happen creates a framework that is both minimal and powerful.
This approach recognizes that the most powerful frameworks are often those that do less, not more. By stepping back and letting your code work directly with the runtime, Happen achieves a rare balance: it provides enough structure to create sophisticated event-driven systems while imposing minimal constraints on how those systems are implemented.
The result is a framework that truly embodies its name: it helps things happen without dictating how they happen.
Last updated