DEV Community

Cover image for How to use custom JSX in Deno?
WJH
WJH

Posted on

2 3

How to use custom JSX in Deno?

This article is meant for Deno authors who wanted to create a frontend library in Deno that utilises JSX without using React.

Before you start, please make sure you're using Deno v1.1.0.

deno upgrade --version=1.1.0

Basically, to create your own JSX types in Deno, you just need to complete the following steps:

1) Think of a name for your framework. For demonstration, I'll use the name Spongebob.

2) Create a tsconfig.json file with the default Deno tsconfig.

3) Update the value of "jsxFactory" in the tsconfig.json to "Spongebob.createElement".

4) Create a file named jsx.ts with the following content:

export namespace Spongebob {
  export const createElement = (tag: string | Function, props: object, ...children: any[]) => {
    if(typeof tag === 'function') {
      return tag({...props, children})
    }
    else {
      return [tag, props, children]
    }
  }
}
declare global {
  namespace JSX {
    interface IntrinsicElements {
      div: {
        id?: string
        style?: { }
      }
    }
  }
}

5) To try out the JSX types, create a file named client.tsx.

import { Spongebob } from "./jsx.ts";

const EntryComponent = () => {
  return (
    <div id="patrick">
      <MySubComponent drugs={["rick", "morty"]} />
    </div>
  );
};

const MySubComponent = (props: { drugs: string[] }) => {
  return (
    <div>
      {props.drugs.map((drug) => <div>{drug}</div>)}
    </div>
  );
};

console.log(JSON.stringify(<EntryComponent />, null, 2));

6) Run this command to test out.

deno run --config tsconfig.json client.tsx

By the way, if you are lazy but you want to try out, you can refer to this repository.
Thank you for reading!

Image of Datadog

The Future of AI, LLMs, and Observability on Google Cloud

Datadog sat down with Google’s Director of AI to discuss the current and future states of AI, ML, and LLMs on Google Cloud. Discover 7 key insights for technical leaders, covering everything from upskilling teams to observability best practices

Learn More

Top comments (1)

Collapse
 
michaelcurrin profile image
Michael Currin • Edited

Deno lint gives a warning:

declare global {
  namespace JSX {
    // ...
  }
}
Enter fullscreen mode Exit fullscreen mode
custom typescript modules are outdated
Enter fullscreen mode Exit fullscreen mode

But this works great:

declare namespace JSX {
  interface IntrinsicElements {
    // deno-lint-ignore no-explicit-any
    [elemName: string]: any;
  }
}
Enter fullscreen mode Exit fullscreen mode

It comes from TS docs - IntrinsicElements.

I've applied this here in my newly-released Deno React app:

src/shims-react.ts

MichaelCurrin - react-deno-quickstart

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs