Skip to main content

What's New

"What's new" has moved to /news and is now called Developer News!

Here you can read about highlighted feature upgrades to the DynaMaker platform. Smaller upgrades and bug fixes are rolled out continuously and might not be brought up on this page. If you experience any problems, let us know at

2023-11-28 Delete configuration and some bug fixes

  • It is now possible to delete saved configurations in DynaMaker. There is also a new optional argument added to LoadSave.openPopupLoad() that adds a delete button to the default load configuration modal.

    enableDeleteConfiguration: true,
  • Fixed a numerical bug in SKYCAD when cutting into a revolve feature.

  • Fixed a bug in room scene options lightIntensity. Setting lightIntensity: 2 is now properly scaling all the lights in the scene by 2, as intended, instead of overwriting the different light intensities. If you need to revert to the old (faulty) behavior, use an object as the value instead.

      // if you had something like this...
    sceneOptions: {
    type: 'room',
    lightIntensity: 2,

    // ...and want to keep the old faulty behavior, replace it with
    sceneOptions: {
    type: 'room',
    lightIntensity: {
    ambient: 2,
    far: 2,
    left: 2,
    near: 2,
    point: 2,
    right: 2,

2023-11-24 More optimizations to DAS plugin

We've deployed futher optimizations to PLUGINS.DAS.generateStepFile()! The new version greatly reduces the amount of data that is sent to the server from the browser, which should speed things up for large assemblies or users on slower connections. To get the new version, open the DAS plugin settings in the dashboard and click on Save.

2023-11-20 Improving performance and hunting bugs

  • Major performance improvements to PLUGINS.DAS.generateStepFile(), especially when working with large assemblies.
  • Added confirmation to production deploy to prevent accidental deploys.
  • Performance improvements to the CAD libraries and the IMPORT2D plugin.
  • Improved loading time of assets when working in the editor.
  • Better handling of PDF files in PLUGINS.IMPORT2D.
  • Added a visual indicator when using a SKYCAD.MeshModel with a source file that could not be loaded.
  • Fixed a bug in the Elfsquad CPQ plugin when DynaMaker is placed in an iframe within another iframe.
  • Various fixes to the integration with Tacton CPQ.
  • Fixed a bug where secret formulas would not deploy correctly.
  • Various fixes and improvements to dimensions in SKYCAD.Layout.
  • Fixed bug related to texture offset on curved surfaces.
  • Fixed a compatibility issue with Safari versions prior to 15.4.

2023-08-18 Various improvements

  • Studio.openInfoModal now returns a Promise that resolves when the modal is closed.
  • SKYPARAM.DropdownItem now has an optional argument "className," which can be used to target specific dropdown items in CSS.
  • Fixed a bug that occasionally resulted in invalid curvatures in exported IFC files.
  • Fixed a bug that caused improperly parsed very large numbers in datasets.
  • Resolved a bug where configurator completion-callback triggers were not properly cleaned up between design step changes, leading to duplicate callback invocations.

2023-06-01 Material overrides, custom fonts, tags filtering and more

This changelog entry presents a variety of notable updates and improvements to the platform. It introduces new functionalities such as material overrides for GLTF/GLB models, a custom fonts API, and a tags filter feature for selective geometry generation when using the component handler. There are also enhancements to dimension styles and defaults, the ability to dynamically show and hide visible metrics, and the addition of an automatic outline. The update further includes the implementation of a clipping planes API for precise control over object visibility, as well as the introduction of a Design Automation Service for seamless generation and export of STEP-files. Lastly, the changelog addresses several bug fixes and compatibility improvements with AutoCAD for generated DXF files.

Material override for GLTF/GLB models

Added the ability to override materials for GLTF/GLB models in the application. This allows developers to apply custom materials or textures to specific parts of the models. Read more about it here.

Custom fonts API

Introduced a custom fonts API that allows developers to define and utilize custom fonts within the application. The default font has been normalized to use Liberation Sans for both the scene and exported drawings, replacing the previous setup of Helvetica for drawings and Liberation Sans for scenes. Read more about it here.

Tags filter when generating geometry from the component handler

Implemented a tags filter feature that enables users to generate geometry selectively based on specific tags assigned to component instances. Read more about it here.

Improved dimension styles and defaults

Enhanced dimension styles and default settings. Improvements include new default options in layouts, new line terminators for dimension lines, and enhanced presentation for compact cases. Read more about it here.

Dynamically show and hide visible metrics

Implemented the ability to dynamically show or hide visible metrics. You can now display or hide specific metrics with a simple function call. Read more about it here.

Automatic outline

We previously introduced selective geometry interaction, which enables users to interact with individual geometry elements instead of the entire model. Additionally, an automatic outline can now be displayed when interacting with geometry, providing visual feedback and improving the user experience. While we're working on more detailed documentation for the automatic outline, please reach out to if you would like to know more.

Clipping planes API

Implemented a clipping planes API that enables users to define and control clipping planes in the application. This feature allows for more precise control over the visibility and display of objects by selectively hiding or revealing portions of the scene.

Studio.setUpdateGeometryFunction((data, worldControls) => {
// ...

const clippedGroupId = 'my-clipped-group'
const clippingPlanes = [new SKYCAD.Plane(0, 0, 1, 10), new SKYCAD.Plane(1, 1, 1, 20)]
worldControls.setClippingPlanes(clippingPlanes, { groupId: clippedGroupId })

worldControls.updateGeometry(geometry, { groupId: clippedGroupId })

While we're working on more detailed documentation for clipping planes, please reach out to if you would like to know more.

Design automation service

With our Design Automation Service, you can now effortlessly generate and export STEP-files from your application regardless of if your app uses static models or not! You can read more about it here and here.

Various improvements

  • Added missing return type for Studio.openParameterModal()
  • Enhanced the handling of some parameter types outside of a configurator in the toolbar
  • Fixed a bug related to save/load of configurations in UI Studio
  • Fixed a bug related to the light position in the room scene
  • Fixed a bug that prevented the loading of RGB encoding from GLB files
  • Fixed a bug that sometimes prevented more than one instance of the same geometry from loading
  • Fixed an issue where the set-camera and request-image commands from top/bottom views would occasionally not have the x-axis positioned horizontally
  • Fixed the UI update for text parameters when their underlying value is updated
  • Corrected the newValue behavior in the setUpdateRule() function for text parameters
  • Fixed an issue with the setValue() function for text parameters
  • Improved compatibility with AutoCAD for generated DXF files

2023-04-19 Form Modal

The recently added Studio.createFormModal() makes it easier to ask for user input, for instance, when submitting a quotation request. You can read more about it here.

2023-03-22 Improved touch controls

This update improves camera rotation, zoom, and pan on touch devices. By default, one finger triggers interaction (selectionEvent), and zoom is done with two fingers. You can change this behavior by using the Studio.updateCameraSettings() function and passing in the desired values for the oneFinger and twoFingers options.

For example, if you want rotation to be triggered by one finger instead of interaction and zoom-and-pan by two fingers, you can use:

touch: {
oneFinger: 'rotate',
twoFingers: 'zoomAndPan',


The default value of the camera setting zoomToMouse has been changed from true to false. We believe this is a more sensible default for most applications. If you want, you can enable zoom-to-mouse like this in your app:

zoomToMouse: true,

2023-03-13 Selective geometry interaction

Until now, all geometry that you add to the scene in DynaMaker has been interactable. From here on, the default behavior for new applications will be that you as a developer get to control what geometry groups can trigger selection events.

You might notice that we've begun to replace the term selection with interaction in the context of events triggered by the mouse or touch screen. This is in part because we think it is a better description of what is actually happening and in part to differentiate it from the and manager.getActiveSelection() API.

To enable interaction events for a given group, set the interactable argument to true when updating the geometry.

Studio.setUpdateGeometryFunction((data, worldControls) => {
// ...
worldControls.updateGeometry(geometryGroup, {
interactable: true,

To not break existing apps, this behavior is opt-in and controlled via an argument called useSelectiveGeometryInteraction in the ADVANCED tab. You can also add this argument manually to your existing application if you would like to use it there.

export function productConfigurationFactory(): STUDIO.IProductConfiguration {
return {
// ...
useSelectiveGeometryInteraction: true,

For even more control over interaction events, you can use the interaction plane. If the mouse/touch does not intersect with any interactable geometry group, the interaction plane is used. By default, the default interaction plane is the ground plane (0, 0, 1, 0).

// set the interaction plane to be the xz-plane offset by 100
const plane = new SKYCAD.Plane(0, 1, 0, 100)

// completely remove the interaction plane

2023-01-25 CSS snippet for mobile layout

Check out this newly added CSS snippet that can help you create a responsive layout for your DynaMaker application!

2023-01-19 Quote File Service

With the new Quote File Service, you can now use your DynaMaker application as a REST API in addition to all its previous capabilities! A common task could be to generate a PDF and attach it to a quotation or send it in an email, fully automated on the server. You can read more about it on its documentation page.

2022-11-09 Improved geometry projection and images in QuickBar

Highlights among the recent updates to DynaMaker are a new SKYCAD function for geometry projection and a more customizable QuickBar with support for custom images and automatic spinners that indicate loading or processing.


It is now possible to include texts, dimensions and images when generating projections. This is done using the new function SKYCAD.project():

SKYCAD.project(geometry: SKYCAD.GeometryGroup, plane: SKYCAD.Plane, args?: {
excludeTags?: (string | string[])[]
}): SKYCAD.Layout

It can also be used to project a SKYMATH.Vector3D onto a SKYCAD.Plane:

SKYCAD.project(vector: SKYMATH.Vector3D, plane: SKYCAD.Plane): SKYMATH.Vector2D

Images in QuickBar

Items passed to Studio.setQuickBarItems() can now have a property image:

action: () => {
// do something

In new apps, the image height is limited to 40 pixels by default. If you wish to change this or to use it in an app created before this change, add the following CSS to the STYLE tab in UI Studio:

.sky-quick-bar-item-container img {
max-height: 40px;

QuickBar items now also handle asynchronous functions by showing a spinner while the action is running. This is similar to how the SKYUI.Button works:

icon: 'download-alt',
action: () => {
return functionThatReturnsAPromise()

Customizable delay for Configurator callback

It is now possible to set the delay for the callback functions connected to a Configurator:

const configurator = new SKYPARAM.Configurator([
// parameters...

// set the completion callback delay to 1500 milliseconds instead of the default 500

configurator.addCompletionCallback((valid, values) => {
// this will run 1500 ms after a changes was made to the configurator

2022-10-10 Some adjustments and fixes

  • The toolbar at the top of the preview in the drawing editor will now stick to the top of the page when scrolling down.
  • Introduced an optimization that prevents very large static sketches from slowing down the editor experience.
  • Updated the Elfsquad plugin to automatically remove the <p></p> that wrapped all text values. Re-sync the plugin to get the latest version.
  • Fixed a bug in the Elfsquad plugin that in very rare cases caused an error when synchronizing.
  • Fixed a bug in SKYDRAWING where the validScales argument in drawing.addContent() could cause an endless loop.
  • Various SKYCAD fixes

2022-10-03 Merge open ends

Some sketches are not fully connected after importing them into the app dashboard which prevents extruding them into 3D geometry. To fix it, you had to use the sketch.mergeOpenEnds() function to connect the lines in the sketch. This is now done by default when creating the static sketch in the dashboard. Since this merge operation is a good idea most of the time, but not always, it is also possible to opt-out when creating the static sketch.

2022-09-14 Lighting adjustment in the room scene

This change only applies to apps that have sceneOptions: { type: 'room' } in ADVANCED.

To better support different materials, especially when working with imported GLTF models, we have updated the default lighting settings of the room scene. If you wish to opt out of this change, you can restore the original lighting settings by copying the following lightIntensity values into your sceneOptions in ADVANCED.

// other options...

sceneOptions: {
type: 'room',

// original room lighting settings
lightIntensity: {
ambient: 0,
point: 5,
far: 2,
near: 8,
left: 5,
right: 10,


Below is the same static model (GLB) shown in three different scene settings:

  1. Clean scene (current default)
  2. Room scene with original settings
  3. New room default settings

The new defaults are:

lightIntensity: {
ambient: 0.4,
point: 5,
far: 1,
near: 1,
left: 1,
right: 1,

2022-05-06 Better type checking and code formatting

The code editor in DynaMaker has been upgraded to catch some common coding patterns that might lead to unexpected errors and to make the code formatting more consistent.

Strict null checks

In the video below, postPositions.find has no guarantee that it will find a position. Previously, accessing position without checking that it is not undefined was not reported as an error by the editor, which could lead to errors occurring in production.

To verify that position exists, you can use an if-statement, for example:

If for some reason it is not possible to do a proper check, you can use the non-null assertion operator to disable the error message. We recommend that you avoid doing this if possible since it increases the risk of your app crashing in production:

You can read more about struct null checks here.

Code formatting

We have upgraded the formatting engine to use Prettier. You can automatically format your code in the DynaMaker editor by pressing shiftaltf or by pressing F1 and then searching for format.

2022-04-27 - Rotation of images

Rotation of an ImageInstance now behaves the same as rotation of a SketchInstance. Previously images were rotated around their center point instead of their lower-left corner. This led to inconsistent behavior, for example when rotating a Layout containing both sketches and images.

Sketch (unchanged)

The blue sketch has a rotation of 0 and the red has a rotation of Math.PI / 2.

Image before

The horizontal image has a rotation of 0 and the vertical has a rotation of Math.PI / 2. The rotation is done around the center of the image.

Image now

The horizontal image has a rotation of 0 and the vertical has a rotation of Math.PI / 2. The rotation is done around the lower left corner of the image.

Update 2022-02-09

With this update, we have cleaned up the SKYCAD.Layout API to make it easier to work with:

  • Deprecated many style-related functions such as getDefaultSketchFillColor() in favor of getDefaultStyle()
  • Deprecated getters for individual element types such as getDimensions() in favor of getElements()
  • Deprecated margins
  • Deprecated size (width and height)
  • Removed the default size (width and height)
  • Removed the default anchors
  • Renamed cropContent () to crop()
  • Renamed getContentBounds() to getBounds()
  • Renamed rotateContent () to rotate()
  • Renamed scaleContent () to scale()
  • Renamed translateContent () to translate()

Update 2022-02-01

This update contains the following changes:

New tutorial: My First App

A new tutorial My First App has been added. It covers the very basics of how to create an application, from template to deployment.

The rest of the tutorials have been updated to fit with the new simplified project and app templates.

Simplified application template

The new application template comes with no components or drawings out-of-the-box. By creating and connecting all the parts of the application, we hope that you as a developer will gain a better understanding of how your application works. Check the new tutorial My First App which covers the first steps of creating an application!

Simplified UI template

Since there are no components in the default project template, the new UI template should be much easier to grasp. Most of the template code is now in the UI tab when starting. As your application grows, you can structure your code into the COMPONENTS, ACTIONS and CONSTANTS tabs.

Although no component is added by default, there are a few lines of commented code that can help you when importing your first component.

Simplified component template

There have been a few changes in the component template as well to make it easier to get started with. Just like in the UI, most template code has been moved to the COMPONENT tab. As your component grows more complex, you should still move geometry logic to GEOM3D and GEOM2D, but when starting it is all contained within generateGeometry() in the Component itself.

PARAMETERS includes a new smart configurator that still works after modifying the component properties. It is intended to help you get started with implementing your custom component and it is recommended to replace it eventually.

Update 2021-11-04

Simplified SKYMATH API

The SKYMATH module has been reworked to be easier to understand and use! Many existing functions have been deprecated and will show up as strikethrough in the code. We recommend that you start using the new functions, but the deprecated function will continue to work as before.

The deprecation message (highlighted in the image above) will give you a hint of what function you can use instead of the deprecated one. In this example, you can replace the call to SKYMATH.addVectors2D(v1, v2) with SKYMATH.add(v1, v2).

Many of the new functions have overload signatures, which means that the same function can work with different inputs. For example, the new SKYMATH.add() works in both 2D and 3D and replaces both SKYMATH.addVectors2D() and SKYMATH.addVectors3D(). It can also add two instances of the new SKYMATH.Matrix class!

SKYMATH.add(new SKYMATH.Vector2D(1, 2), new SKYMATH.Vector2D(2, 1)) // returns new SKYMATH.Vector2D(3, 3)
SKYMATH.add(new SKYMATH.Vector3D(1, 2, 3), new SKYMATH.Vector3D(3, 2, 1)) // returns new SKYMATH.Vector2D(4, 4, 4)

You can see all the overloads by clicking the arrows (or using the up and down arrows on your keyboard) next to the function signature in the code editor.

You can read more about function overloads in the official TypeScript handbook.

Update 2021-10-21

Geometry loading effect

When geometry is being updated, after a Studio.requestGeometryUpdate(), the previous geometry will become blurred to indicate to the user that an update is running.

You can change this loading effect using CSS. For example, to make the geometry 50% grayscale in addition to the blur effect, add the following to the STYLE tab:

canvas.loading {
filter: blur(2px) grayscale(50%);

Applications created before this change was released can opt-in by adding a style rule in the STYLE tab. Here is the default rule used in new applications:

canvas.loading {
filter: blur(2px);

You can opt out of this change altogether in the ADVANCED tab:

export function productConfigurationFactory(): STUDIO.IProductConfiguration {
return {
disableLoadingEffectOnGeometryUpdate: true,
// other settings...

Update 2021-10-07

Simplified camera API

The functions used for handling the camera have been reworked and many existing functions have been deprecated. Although we recommend that you start using the new camera functions, the deprecated function will continue to work as before, but will show up as strikethrough in the code:

There are now four main camera functions:


You can read more about the new camera API here!

Update 2021-08-30

Editor layout change

We have simplified the layout of how you access the different files in the code editor. By flattening the file menu to a single list on the right-hand side, you can open any file in the editor with one click.

Easier access to the Studio service when working in UI

The UI template has been updated so that the Studio service is global in the UI file. This only applies to new projects that you create from this update and forward. If you want you can create a new project and copy-paste this change into your existing project.

Update 2021-06-20

Some CAD-related classes and functions have been moved from SKYMATH to SKYCAD. Your code has been automatically updated to reflect these changes.

RefPlane moved and renamed

SKYMATH.RefPlane is now SKYCAD.Plane.

Bounds moved

SKYMATH.Bounds2D and SKYMATH.Bounds3D are now SKYCAD.Bounds2D and SKYCAD.Bounds3D respectively.

Update 2021-06-01

This update to DynaMaker simplifies working with the CAD libraries by merging the whole SKYSKETCH namespace into the SKYCAD namespace.

How does this update affect existing projects?

All references to SKYSKETCH have been changed to SKYCAD, so this update should be non-breaking. Your projects will work just like before, but instead of writing new SKYSKETCH.Layout() to create a new Layout, you write new SKYCAD.Layout() instead.

Update 2021-02-17

This update to DynaMaker, which should not break any existing applications, makes it easier to use the ComponentHandler and brings out-of-the-box support for saving and loading.

How does this update affect existing projects?

This update introduces a new pattern of interacting with the ComponentHandler. Existing projects may choose to continue using the old pattern and can ignore the changes described below. If you create a new component in an existing project, you may have to update it manually to make it look like before. Another way, which may be easier, is to fork an existing component in your project and build from there.

Changes to the ComponentHandler

Define components

The ComponentHandler function defineComponent() is no longer needed and should not be used.

Add components

You no longer have to add a type string when adding components to the ComponentHandler.

// old
componentHandler.add('accessory', new ACCESSORY.Component())

// new
componentHandler.add(new ACCESSORY.Component())

If you need to separate the same component class into logical groups, you may do so using tags.

// old
componentHandler.add('accessory-top', new ACCESSORY.Component())
componentHandler.add('accessory-bottom', new ACCESSORY.Component())
const topAccessories = componentHandler.getInstances('accessory-top')

// new
componentHandler.add(new ACCESSORY.Component(), { tags: ['top'] })
componentHandler.add(new ACCESSORY.Component(), { tags: ['bottom'] })
const topAccessories = componentHandler.getInstances(ACCESSORY.Component).filter((inst) => inst.hasTag('top'))

Get components, instances and bundles

// old

// new (provides code completion!)

Clear a specific component

// old

// new, by class
// new, by tag

New application and component templates

When you create a new project or component, you might notice that the template has changed with this update.


  • Extending STUDIO.BaseComponent

Components now extend the STUDIO.BaseComponent class, which adds functionality such as the getProperty function to your component automatically.

  • Constructor arguments

It is best practice to have a Component constructor without input arguments. If you need to change the values of the properties you should call component.setProperties({ ... }) after creating the component. The template has been updated to reflect this.

// old
constructor(args: Partial<CONSTANTS.Properties> = {}) {
const width = args.width ?? 100
const depth = args.depth ?? 100
const height = args.height ?? 100 = { width, depth, height }

// new
constructor() {

depth: 100,
height: 100,
width: 100,

Save and load

If your project has authentication such as JSON Web Tokens or Auth0 enabled, the new application template together with the updated ComponentHandler allows for saving and loading configurations in your deployed project by default.

While developing

You can now test save and load directly in the UI Editor editor.

Update 2020-10-20

This update to DynaMaker, which should not break any existing projects, makes it easier to create and use geometry.


You will notice that some classes and functions that you've used previously have been deprecated. Deprecated classes and functions still work, but should be avoided in new code that you write.

Deprecated classes and functions will appear as strikethrough in the editor

Action Events

The way that actions related to the product are called from the UI code has changed for new projects. The new way brings a better developer experience through code completion and type checking.

// old way

// new way

The Geometry API

The way that we create and group geometry (models and sketches) has changed with this update.

  • The new class SKYCAD.GeometryGroup should be used for grouping geometry (parent-child structure)
  • SKYCAD.ModelInstance should no longer be used as a parent of other models via addChildInstance()
  • ComponentInstance.getModelInstance() is replaced by ComponentInstance.generateGeometry() and now returns a SKYCAD.GeometryGroup
  • SKYCAD.GeometryOnPlane has been deprecated in favor of the similar SKYCAD.LayoutOnPlane
  • SKYCAD.Model has been renamed to SKYCAD.ParametricModel to differentiate it from SKYCAD.MeshModel
  • SKYCAD.ModelMaterial has been renamed SKYCAD.Material

Geometry And The Component Handler

The component handler has been updated with some new functionality that makes it simple to gather all the geometry from your components!

componentHandler.generateAllGeometry(): SKYCAD.GeometryGroup
componentHandler.generateGeometry(componentType: string): SKYCAD.GeometryGroup
componentHandler.generateAllLightweightGeometry(): SKYCAD.GeometryGroup
componentHandler.generateLightweightGeometry(componentType: string): SKYCAD.GeometryGroup

These functions position the geometry for each component instance. They require that your components implement the generateGeometry() and generateLightweightGeometry() functions respectively.

Updating The Scene

For new projects, getModels() and getSketches() in the COMPONENTS tab of the UI Editor have been replaced by updateGeometry() and updateLightweightGeometry(), to give you more fine-grained control over what geometry should update and when.

// the old way

export function getModels(manager: STUDIO.Manager) {
// ...

export function getSketches(manager: STUDIO.Manager) {
// ...
// the new way

* Add new Geometry to the scene depending on app state
export function updateGeometry(data: STUDIO.DataForUpdateGeometry, worldControls: STUDIO.WorldControls) {
const geometryGroup = new SKYCAD.GeometryGroup()

switch (data.designStep) {

worldControls.updateGeometry(geometryGroup, { groupId: 'primary' })

* Optional lightweight geometry
export function updateLightweightGeometry(data: STUDIO.DataForUpdateGeometry, worldControls: STUDIO.WorldControls) {
const geometry = data.componentHandler.generateAllLightweightGeometry()
worldControls.updateGeometry(geometry, { groupId: 'lightweight' })

Instead of calling Studio.update() you should use Studio.requestGeometryUpdate() and Studio.requestLightweightGeometryUpdate() together with this new update geometry pattern.

Components And The Configurator

New components created from this point forward have a new pattern for generating their configurator(s). Instead of implementing the configure() function on the component, you should export one or more functions from the PARAMETERS tab in the component-maker.

You can switch between different configurators with the dropdown in the upper left corner

In the application, use the generator functions to generate the configurator instead of calling configure().

// old way
export function actionEvent(type: string, args: any, manager: STUDIO.Manager) {
// ...

switch (type) {
case 'configure-component':
return component.configure()

// new way
export function configureMainComponent() {
const component = getMainComponent()
return COMPONENT1.generateConfigurator(component)