FOAM (Feature-Oriented Active Modeller) is a cross-platform, cross-tier, full-stack application framework designed for building enterprise-level applications rapidly. Created by Google engineers, FOAM provides a comprehensive Model-Driven Development (MDD) approach that significantly reduces the amount of boilerplate code you need to write.
Unlike most frameworks that are restricted to one language or tier, FOAM supports:
Think of FOAM as a meta-programming framework that lets you define your application’s data models once, and then automatically generates the views, controllers, networking code, storage adapters, and business logic from those definitions—across all tiers and platforms.
This end-to-end-to-end solution is unusual in the framework landscape. Most developers must manually integrate multiple point-solutions: a web framework here, a mobile framework there, a server framework somewhere else, each with different paradigms and patterns. FOAM solves the integration problem by providing a unified modeling approach that works everywhere.
FOAM operates on a simple but powerful principle: define your models declaratively, and let the framework generate everything else. Instead of writing repetitive CRUD operations, validation logic, UI components, and serialization code for each feature, you describe what your data looks like and how it should behave—FOAM handles the rest.
At the heart of FOAM is the model definition system. You define classes with properties, methods, and behaviors using a declarative syntax:
foam.CLASS({
package: 'com.example',
name: 'Person',
properties: [
{ name: 'firstName', class: 'String' },
{ name: 'lastName', class: 'String' },
{ name: 'age', class: 'Int' },
{ name: 'email', class: 'EMail' }
]
});
From this simple definition, FOAM automatically generates:
FOAM implements reactive data binding out of the box. When a property changes, all dependent views and computed values automatically update. This eliminates the need for manual DOM manipulation and state synchronization.
FOAM applications run on:
The same model definitions work across all platforms with minimal platform-specific code. This is what makes FOAM truly unique—most frameworks are point-solutions for one language or tier. FOAM provides an end-to-end-to-end solution, eliminating the complex integration work typically required when stitching together separate web, mobile, and server frameworks.
FOAM includes a rich set of pre-built, customizable UI components:
FOAM provides a unified DAO (Data Access Object) pattern for data persistence:
You can switch between storage mechanisms without changing your application code.
FOAM extends JavaScript’s prototype-based inheritance with a more structured class system. Every FOAM class is defined using foam.CLASS() and can inherit from other FOAM classes:
foam.CLASS({
package: 'com.example',
name: 'Employee',
extends: 'com.example.Person',
properties: [
{ name: 'employeeId', class: 'String' },
{ name: 'department', class: 'String' },
{ name: 'salary', class: 'Float' }
],
methods: [
function getFullName() {
return this.firstName + ' ' + this.lastName;
}
]
});
Properties are the building blocks of FOAM models. They’re much more powerful than simple JavaScript properties:
FOAM automatically generates views from your models. You can also create custom views that bind to your data:
foam.CLASS({
name: 'PersonDetailView',
extends: 'foam.u2.View',
methods: [
function render() {
this
.start('div').addClass('person-detail')
.start('h2').add(this.data.firstName$, ' ', this.data.lastName$).end()
.start('p').add('Email: ', this.data.email$).end()
.start('p').add('Age: ', this.data.age$).end()
.end();
}
]
});
The $ syntax creates reactive bindings that automatically update when data changes.
FOAM excels in scenarios where you need to:
The end-to-end-to-end nature of FOAM means you can define a User model once and have it work identically in your FOAM web client, your Swift iOS app, your Java Android app, and your Java server—all from the same model definition.
The truth is, FOAM’s applicability is broader than you might initially think. Consider the ChromeOS system calculator - a seemingly simple application that doesn’t exploit any of FOAM’s traditional strengths (it’s not client-server, not cross-platform, not cross-language, and doesn’t work with data). Yet when rewritten in FOAM with Material Design:
This was deliberately chosen as a “worst-case” scenario for FOAM, yet it dramatically outperformed the conventional implementation.
The lesson: Model-driven development’s benefits (smaller code, fewer defects, easier maintenance) apply even to applications that seem too simple or specialized for frameworks.
FOAM might genuinely not be suitable when:
But “too simple” is rarely a valid reason not to use FOAM.
To begin working with FOAM:
foam.CLASS()The learning curve can be steep initially, but once you understand the model-driven approach, FOAM enables extremely rapid development with minimal code.
As you dive into FOAM, focus on understanding:
FOAM represents a fundamentally different approach to JavaScript development. Instead of manually writing every piece of functionality, you describe your application’s structure and let the framework generate the implementation. This Model-Driven Development approach can dramatically accelerate development while maintaining code quality and consistency—especially for complex, data-centric applications.
The trade-off is learning a new way of thinking about application development and accepting some framework conventions. For the right project, FOAM can be incredibly powerful.