How to use custom JSX in Deno?
WJH

WJH @wongjiahau

Joined:
Apr 30, 2018

How to use custom JSX in Deno?

Publish Date: Jun 16 '20
10 1

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!

Comments 1 total

  • Michael Currin
    Michael CurrinFeb 21, 2021

    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

Add comment