LikeC4 API
You can access and traverse your architecture model programmatically using the LikeC4 Model API.
Ensure you have likec4
in your dependencies:
npm i likec4
pnpm add likec4
yarn add likec4
bun add likec4
You can initiate LikeC4 API from a directory with source files or from a string with DSL source.
From workspace
Section titled “From workspace”Recursively search and parse source files:
import { LikeC4 } from 'likec4'
const likec4 = await LikeC4.fromWorkspace('/path/to/workspace')
Method also accepts options:
Property | Description |
---|---|
printErrors | if model is invalid, errors are reported to the logger (default true ) |
throwIfInvalid | return rejected promise if model is invalid (default false ) |
logger | Whenever to use default (console), vite logger or your custom implementation Disable with false |
graphviz | wasm (default) or binary - use local binaries of Graphviz (“dot”) or bundled WASM |
watch | Whether to watch for changes in the workspace. (default false ) |
mcp | Whether to start MCP server. - false - do not start MCP server (default) - "stdio" - use stdio transport,- {"port": number} - use http transport on specified port |
From source
Section titled “From source”Parse from the string:
import { LikeC4 } from "likec4"
const likec4 = await LikeC4.fromSource(` specification { element system element user } model { customer = user 'Customer' cloud = system 'System' } views { view index { include * } }`)
Dispose
Section titled “Dispose”If you initialized LikeC4 with watch mode or enabled MCP server, you should dispose it:
import { LikeC4 } from 'likec4'
const likec4 = await LikeC4.fromWorkspace('/path/to/workspace', { watch: true, mcp: { port: 33335 },})
// Cleanup resourcesawait likec4.dispose()
When the model is initialized, you can use the following methods to query and traverse it.
Two types of model (with similar API):
- LikeC4Model.Computed - includes computed views (from predicates), fast, synchronous, enough to traverse but not ready for rendering.
- LikeC4Model.Layouted - extends computed model with layout data (dimensions, positions), that is needed for rendering.
Example
Section titled “Example”import { LikeC4 } from "likec4"
const likec4 = await LikeC4.fromSource(`....`)
// Validation errorsconsole.log(likec4.getErrors())
// Traverse the modelconst model = likec4.computedModel()
// Get elements of some kindconst elements = model.elementsOfKind('kind1')
// Use where operator to filter elements:// kind is 'kind1' and (tag is 'tag2' or tag is not 'tag3')const elements = model.elementsWhere({ and: [ { kind: 'kind1' }, { or: [ { tag: 'tag2' }, { tag: { neq: 'tag3', }, }, ], }, ],})
// Get views that include the elementmodel .element('cloud.backend.api') .views()
// Get source elements of incoming relationships (filter by tags)model .element('cloud.backend.api') .incoming() // relationships incoming to the element .filter(r => r.isTagged('http')) // filter by tags .map(r => r.source) // get source elements
const diagram = await likec4.layoutedModel().view('index')
LikeC4Model
Section titled “LikeC4Model”Model API provides methods to query and traverse the whole model.
interface LikeC4Model { /** * Returns the root elements of the model. */ roots(): Element[]; /** * Returns all elements in the model. */ elements(): Element[]; /** * Returns a specific element by its FQN. */ element(id: Fqn): Element; /** * Returns all relationships in the model. */ relationships(): Relationship[]; /** * Returns a specific relationship by its ID. */ relationship(id: RelationID): Relationship; /** * Returns all views in the model. */ views(): ReadonlyArray<LikeC4ViewModel>; /** * Returns a specific view by its ID. */ view(viewId: ViewID): LikeC4ViewModel; /** * Returns the parent element of given element. * @see ancestors */ parent(element: ElementOrFqn): Element | null; /** * Get all children of the element (only direct children), * @see descendants */ children(element: ElementOrFqn): Element[]; /** * Get all sibling (i.e. same parent) */ siblings(element: ElementOrFqn): Element[]; /** * Get all ancestor elements (i.e. parent, parent’s parent, etc.) * (from closest to root) */ ancestors(element: ElementOrFqn): Element[]; /** * Get all descendant elements (i.e. children, children’s children, etc.) */ descendants(element: ElementOrFqn): Element[]; /** * Incoming relationships to the element and its descendants * @see incomers */ incoming(element: ElementOrFqn, filter?: 'all' | 'direct' | 'to-descendants'): Relationship[]; /** * Source elements of incoming relationships */ incomers(element: ElementOrFqn, filter?: 'all' | 'direct' | 'to-descendants'): Element[]; /** * Outgoing relationships from the element and its descendants * @see outgoers */ outgoing(element: ElementOrFqn, filter?: 'all' | 'direct' | 'from-descendants'): Relationship[]; /** * Target elements of outgoing relationships */ outgoers(element: ElementOrFqn, filter?: 'all' | 'direct' | 'from-descendants'): Element[];}
Check sources for methods - LikeC4Model
LikeC4DeploymentModel
Section titled “LikeC4DeploymentModel”API provides methods to query and traverse deployment model.
import { LikeC4 } from "likec4"
const likec4 = await LikeC4.fromSource(`....`)const model = likec4.computedModel()
// Get deployment modelconst deployment = model.deployment
// Get elements of some kindfor (const instance of deployment.instancesOf('cloud.backend.api')) { // ...}
LikeC4ViewModel
Section titled “LikeC4ViewModel”View model API provides methods to query and traverse elements and relationships that are included in the view.
import { LikeC4 } from "likec4"
const likec4 = await LikeC4.fromSource(`....`)const model = likec4.computedModel()
for (const view of model.views()) { if (view.isDynamicView()) { // ... }}
Model Builder
Section titled “Model Builder”Type-safe builder available from @likec4/core/builder
.
Builder can be used to create model programmatically and supports two styles:
import { Builder } from "@likec4/core/builder"
const m = Builder .specification({ elements: { actor: { style: { shape: 'person', }, }, system: {}, component: {}, }, relationships: { likes: {}, }, tags: ['tag1', 'tag2', 'tag1'], }) .model(({ actor, system, component, relTo, rel }, _) => _( actor('alice'), actor('bob'), rel('alice', 'bob', { tags: ['tag1'], // you get code completion for tags kind: 'likes', // code completion for kind }), system('cloud', { tags: ['tag1', 'tag2'] }).with( component('backend').with( component('api'), component('db'), // code completion for relationships rel('cloud.backend.api', 'cloud.backend.db') ), component('frontend').with( relTo('cloud.backend.api') ), ), ) ) .views(({ view, viewOf, $include, $style }, _) => _( view('index', 'Index').with( $include('cloud.*'), ), viewOf('ui', 'cloud.ui').with( // code completion for predicates $include('* -> cloud.**'), $style('cloud.ui', { color: 'red' }), ), ) ) .toLikeC4Model()
import { Builder } from "@likec4/core/builder"
// Get composition functions for given specificationconst { model: { model, actor, system, component, rel, relTo, }, views: { view, viewOf, views, $include, $style, }, builder,} = Builder.forSpecification({ elements: { actor: { style: { shape: 'person', }, }, system: {}, component: {}, }, relationships: { likes: {}, }, tags: ['tag1', 'tag2', 'tag1'],})
const b1 = builder.with( model( actor('alice'), actor('bob'), rel('alice', 'bob', { tags: ['tag1'], kind: 'likes', }), system('cloud', { tags: ['tag1', 'tag2'] }).with( component('backend').with( component('api'), component('db'), rel('cloud.backend.api', 'cloud.backend.db') ), component('frontend').with( relTo('cloud.backend.api') ), ), ))
const b2 = b1.with( views( view('index', 'Index').with( $include('cloud.*'), ), viewOf('ui', 'cloud.ui').with( $include('* -> cloud.**'), $style('cloud.ui', { color: 'red' }), ), )).toLikeC4Model()
You can mix both styles, depending on your preference and use cases.