Skip to content

Model reference

Reference of the model objects you get from LikeC4: the logical model, its elements, the deployment model and views. All of them have the same API for the computed and the layouted model.

LikeC4Model provides methods to query and traverse the whole model. Methods that return several items return iterators: use iterator helpers (.filter(), .map(), .toArray()) or spread them into an array.

interface LikeC4Model {
/**
* Returns the root elements of the model.
*/
roots(): Iterator<ElementModel>;
/**
* Returns all elements in the model.
*/
elements(): Iterator<ElementModel>;
/**
* Returns a specific element by its FQN, throws if not found.
* @see findElement
*/
element(id: Fqn): ElementModel;
/**
* Returns the element by its FQN, or null if not found.
*/
findElement(id: string): ElementModel | null;
/**
* Returns all elements of the given kind.
*/
elementsOfKind(kind: ElementKind): Iterator<ElementModel>;
/**
* Returns all elements that match the where operator.
*/
elementsWhere(where: WhereOperator): Iterator<ElementModel>;
/**
* Returns all model relationships.
*/
relationships(): Iterator<RelationshipModel>;
/**
* Returns a specific relationship by its ID, throws if not found.
*/
relationship(id: RelationId): RelationshipModel;
/**
* Returns all model relationships that match the where operator.
*/
relationshipsWhere(where: WhereOperator): Iterator<RelationshipModel>;
/**
* Returns elements, relationships and views with the given tag.
*/
findByTag(tag: Tag, type?: 'elements' | 'relationships' | 'views'): Iterator<...>;
/**
* Returns all views in the model.
*/
views(): Iterator<LikeC4ViewModel>;
/**
* Returns a specific view by its ID, throws if not found.
* @see findView
*/
view(viewId: ViewId): LikeC4ViewModel;
/**
* Returns the view by its ID, or null if not found.
*/
findView(viewId: string): LikeC4ViewModel | null;
/**
* The deployment model.
*/
readonly deployment: LikeC4DeploymentModel;
/**
* Returns the parent element of given element.
* @see ancestors
*/
parent(element: ElementOrFqn): ElementModel | null;
/**
* Get all children of the element (only direct children)
* @see descendants
*/
children(element: ElementOrFqn): ReadonlySet<ElementModel>;
/**
* Get all siblings (i.e. same parent)
*/
siblings(element: ElementOrFqn): Iterator<ElementModel>;
/**
* Get all ancestor elements (i.e. parent, parent’s parent, etc.)
* (from closest to root)
*/
ancestors(element: ElementOrFqn): Iterator<ElementModel>;
/**
* Get all descendant elements (i.e. children, children’s children, etc.)
*/
descendants(element: ElementOrFqn): Iterator<ElementModel>;
/**
* Incoming relationships to the element and its descendants
*/
incoming(element: ElementOrFqn, filter?: 'all' | 'direct' | 'to-descendants'): Iterator<RelationshipModel>;
/**
* Outgoing relationships from the element and its descendants
*/
outgoing(element: ElementOrFqn, filter?: 'all' | 'direct' | 'from-descendants'): Iterator<RelationshipModel>;
}

Check sources for all methods: LikeC4Model.

model.element(id) returns an ElementModel. It has the element properties (id, kind, title, description, technology, tags, links, metadata) and methods to traverse from it:

interface ElementModel {
parent: ElementModel | null;
children(): ReadonlySet<ElementModel>;
ancestors(): Iterator<ElementModel>;
descendants(sort?: 'asc' | 'desc'): Iterator<ElementModel>;
siblings(): Iterator<ElementModel>;
/**
* Incoming relationships, and source elements of them
*/
incoming(filter?: 'all' | 'direct' | 'to-descendants'): Iterator<RelationshipModel>;
incomers(filter?: 'all' | 'direct' | 'to-descendants'): Iterator<ElementModel>;
/**
* Outgoing relationships, and target elements of them
*/
outgoing(filter?: 'all' | 'direct' | 'from-descendants'): Iterator<RelationshipModel>;
outgoers(filter?: 'all' | 'direct' | 'from-descendants'): Iterator<ElementModel>;
/**
* Views that include the element
*/
views(): ReadonlySet<LikeC4ViewModel>;
/**
* Deployed instances of the element
*/
deployments(): Iterator<DeployedInstanceModel>;
isTagged(tag: string): boolean;
hasMetadata(): boolean;
getMetadata(): Record<string, string | string[]>;
getMetadata(key: string): string | string[] | undefined;
}

Check sources for all methods: ElementModel.

Metadata values are strings or arrays of strings. Boolean values are stored as strings ('true', 'false'). getMetadata() returns all metadata, getMetadata(key) returns one value: check with Array.isArray which one you got.

import { LikeC4 } from 'likec4'
const likec4 = await LikeC4.fromSource(`
specification {
element service
element application
}
model {
api = service 'API Gateway' {
metadata {
version '3.2.1'
teams ['platform', 'payments']
regions ['us-east-1', 'eu-west-1']
critical true
}
}
frontend = application 'Frontend' {
metadata {
framework 'React'
teams 'web'
}
}
}
`)
const model = await likec4.computedModel()
const api = model.element('api')
if (api.hasMetadata()) {
// All metadata as an object
console.log(api.getMetadata())
// { version: '3.2.1', teams: ['platform', 'payments'], regions: ['us-east-1', 'eu-west-1'], critical: 'true' }
const version = api.getMetadata('version') // '3.2.1'
const critical = api.getMetadata('critical') === 'true' // true
}
// A value can be a string or an array of strings
const teams = api.getMetadata('teams')
if (Array.isArray(teams)) {
console.log(`Owned by ${teams.length} teams: ${teams.join(', ')}`)
} else if (teams) {
console.log(`Owned by ${teams}`)
}
// Elements owned by a team, whether the value is a string or an array
const platformElements = model.elements()
.filter(el => {
const teams = el.getMetadata('teams')
return Array.isArray(teams) ? teams.includes('platform') : teams === 'platform'
})
.toArray()
// Elements deployed to more than one region
const multiRegion = model.elements()
.filter(el => {
const regions = el.getMetadata('regions')
return Array.isArray(regions) && regions.length > 1
})
.toArray()
// Group elements by framework
const byFramework = Map.groupBy(
model.elements().filter(el => typeof el.getMetadata('framework') === 'string'),
el => el.getMetadata('framework') as string,
)

model.deployment provides methods to query and traverse the deployment model.

import { LikeC4 } from 'likec4'
const likec4 = await LikeC4.fromWorkspace('/path/to/workspace')
const model = await likec4.computedModel()
const deployment = model.deployment
// Deployed instances of an element
for (const instance of deployment.instancesOf('cloud.backend.api')) {
console.log(`${instance.id} runs on ${instance.parent.title}`)
}
// Deployment nodes of some kind
const clusters = deployment.nodesOfKind('kubernetes').toArray()
// A specific deployment node or instance
const node = deployment.node('prod.eu')
const instance = deployment.instance('prod.eu.api')

Check sources for all methods: LikeC4DeploymentModel.

LikeC4ViewModel provides methods to query and traverse the elements and relationships included in a view.

import { LikeC4 } from 'likec4'
const likec4 = await LikeC4.fromWorkspace('/path/to/workspace')
const model = await likec4.layoutedModel()
for (const view of model.views()) {
if (view.isDynamicView()) {
// ...
}
// Elements included in the view
for (const node of view.elements()) {
console.log(node.element.id)
}
}
const view = model.view('index')
view.includesElement('cloud.backend.api') // true or false
view.edges() // edges between the nodes
view.$layouted // layouted view, with manual layout applied, ready for rendering

Check sources for all methods: LikeC4ViewModel.