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 |
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 * } }`)
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
LikeC4ViewModel
Section titled “LikeC4ViewModel”View model API provides methods to query and traverse elements and relationships that are included in the view.
LikeC4DeploymentModel
Section titled “LikeC4DeploymentModel”API provides methods to query and traverse deployment model.
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.