To be able to easily create HTMLElements in your code, we recommend setting up JSX in your build environment with our simple JSX runtime. JSX is a syntax extension to JavaScript that allows you to write HTML-like code in your JavaScript files. It is not required to use JSX, but it is in our opinion the best way to “template” our product data into the DOM, since it has the same syntax as HTML but operates perfectly with JavaScript.


You must be using babel. If you’re using webpack, you probably already do.


Add a depict helper package and a babel plugin. The babel plugin contains react in the name but we’ll configure it for plain javascript.

npm install @depict-ai/utilishared @babel/plugin-transform-react-jsx

Set up an alias that always refers to the base directory of your project

You need to have an import alias set up which always refers to your project root, no matter from which file it comes from. When using parcel, this is ~ by default.

When using webpack, do the following:

  1. Locate your Webpack configuration file: Typically, this file is named webpack.config.js and is located in the root directory of your project.

  2. Define an alias: In your configuration file, find the resolve field (or create it if it doesn’t exist) and within it, define an alias that maps ~ to your project root directory.

Here is an example:

const path = require('path');

module.exports = {
  // other config here...

  resolve: {
    alias: {
      '~': path.resolve(__dirname, '')

In this example, path.resolve(__dirname, '') returns the absolute path of the directory containing the current module file (webpack.config.js). Therefore, ~ points to the project root directory, if the config file is located there. If it’s not, please update the path accordingly.

Set up babel

Add the following to your babel config file:

  "plugins": [
        "throwIfNamespace": false,
        "runtime": "automatic",
        "importSource": "~"

Adding the custom JSX runtime

Create a file called jsx-runtime.js in your project root with the following contents:

export * from "@depict-ai/utilishared";

Adding types

If you’re using typescript, you probably also want some types. These aren’t perfect, but they’re probably good enough. At least a lot better than templating with strings or document.createElement.

  1. Create a jsx.d.ts file in your project with the following content:
  1. Update your tsconfig to include following:
  "compilerOptions": {
    // compiler options...
    "jsx": "preserve"
  "include": [
     // other includes...

How to use

Basic usage

Some examples:

const text = "hello world";
const element = <div>{text}</div>;

Equals to:

const text = "hello world";
const element = document.createElement("div");


You can create functions and use them as components. They have to return an HTMLElement, an array of HTMLElements or a string or number. If they return null or undefined, their return value will be ignored.

const MyComponent = ({ text }) => {
  return <div>{text}</div>;

And then

const element = (
    <MyComponent text="hello world" />
    <MyComponent text="Foo bar" />

element is now a HTMLDivElement with two children: two HTMLDivElement’s with in turn two Text-nodes as childNodes.

Event listeners

To add event listeners, use .addEventListener:

const MyComponent = ({ text }) => {
  const onMouseOver = () => {
    console.log("Mouse over!");

  const div = <div>{text}</div>;
  div.addEventListener("mouseover", onMouseOver);
  return div;

Except for click where you can simply do:

const MyComponent = ({ text }) => {
  const onClick = () => {

  return <div onClick={onClick}>{text}</div>;


You can use ternaries to branch. Generally, you can put any JS expression into {}:

const MyComponent = ({ text }) => {
  const attributeValue = "I'm an atribute";
  return <div data-attribute={attributeValue}>{Math.random() > 0.5 ? text : ""}</div>;

Please let us know if you encounter any issues or if this guide worked for you.