Frameworks

Cosmic integrates seamlessly with popular frameworks. Select your prefered framework and learn how to get started delivering Cosmic-powered content.

Next.js

Follow the steps below to get started with Cosmic to power content for your Next.js application.

Install a new Next.js app

npx create-next-app@latest cosmic-next

Answer the prompts with the following answers:

  1. Would you like to use TypeScript? Yes
  2. Would you like to use ESLint? Yes
  3. Would you like to use Tailwind CSS? Yes
  4. Would you like to use src/ directory? No
  5. Would you like to use App Router? (recommended) Yes
  6. Would you like to customize the default import alias (@/*)? No

Go into the project folder.

cd cosmic-next

Install the Cosmic JavaScript SDK

Install the Cosmic JavaScript SDK in the location of the codebase.

npm i @cosmicjs/sdk

Add an Object type in the Cosmic dashboard

Log in to the Cosmic dashboard and create a new Blog Posts Object type in a new or existing Project with the following metafields:

  1. Image: Image type with key image
  2. Content: Rich text with key content

Blog model

Add content

Add a few blog posts to get some content ready to be delivered.

Add the following code to your app/page.tsx file

// app/page.tsx
import { createBucketClient } from '@cosmicjs/sdk';
const cosmic = createBucketClient({
  bucketSlug: process.env.BUCKET_SLUG || '',
  readKey: process.env.BUCKET_READ_KEY || '',
});

export default async function Home() {
  const { objects: posts } = await cosmic.objects
    .find({
      type: 'blog-posts',
    })
    .props('title,metadata.image,metadata.content');
  return (
    <>
      {posts?.map(
        (post: {
          title: string,
          metadata: { image: { imgix_url: string }, content: string },
        }) => {
          return (
            <div key={post.title}>
              <div>{post.title}</div>
              <div>
                <img
                  src={`${post.metadata.image.imgix_url}?w=500&auto=format,compression`}
                  alt={post.title}
                />
              </div>
              <div
                dangerouslySetInnerHTML={{ __html: post.metadata.content }}
              />
            </div>
          );
        }
      )}
    </>
  );
}

Add your Cosmic API keys

In a new file titled .env.local add the following environment variables and make sure to switch out the values with your Cosmic API keys found in Project / API keys.

# .env.local
BUCKET_SLUG=add_your_bucket_slug_here
BUCKET_READ_KEY=add_your_bucket_read_key_here

Start the app

Start your app with the following command, go to http://localhost:3000, and see your blog posts.

npm run dev

Astro

Follow the steps below to get started with Cosmic to power content for your Astro application.

Install a new Astro app

npm create astro@latest

Answer the prompts

Answer the question: "How would you like to start your new project?" with Include sample files..

Install the Cosmic JavaScript SDK

Install the Cosmic JavaScript SDK in the location of the codebase.

npm i @cosmicjs/sdk

Add an Object type in the Cosmic dashboard

Log in to the Cosmic dashboard and create a new Blog Posts Object type in a new or existing Project with the following metafields:

  1. Image: Image type with key image
  2. Content: Rich text with key content

Blog model

Add content

Add a few blog posts to get some content ready to be delivered.

Add the following code to your src/pages/index.astro file

---
// src/pages/index.astro
import Layout from "../layouts/Layout.astro";
import { createBucketClient } from "@cosmicjs/sdk";
const cosmic = createBucketClient({
  bucketSlug: import.meta.env.BUCKET_SLUG || "",
  readKey: import.meta.env.BUCKET_READ_KEY || "",
});

const { objects: posts } = await cosmic.objects
  .find({
    type: "blog-posts",
  })
  .props("title,metadata.image,metadata.content");
---

<Layout title="Welcome to Astro.">
  <main>
    {
      posts?.map(
        (post: {
          title: string;
          metadata: { image: { imgix_url: string }; content: string };
        }) => {
          return (
            <>
              <div>{post.title}</div>
              <div>
                <img
                  src={`${post.metadata.image.imgix_url}?w=500&auto=format,compression`}
                  alt={post.title}
                />
              </div>
              <div set:html={post.metadata.content} />
            </>
          );
        }
      )
    }
  </main>

  <style>
    main {
      margin: auto;
      padding: 1rem;
      width: 800px;
      max-width: calc(100% - 2rem);
      color: white;
      font-size: 20px;
      line-height: 1.6;
    }
  </style>
</Layout>

Add your Cosmic API keys

In a new file titled .env add the following environment variables and make sure to switch out the values with your Cosmic API keys found in Project / API keys.

# .env
BUCKET_SLUG=add_your_bucket_slug_here
BUCKET_READ_KEY=add_your_bucket_read_key_here

Start the app

Start your app with the following command, go to http://localhost:4321, and see your blog posts.

npm run dev

Remix

Follow the steps below to get started with Cosmic to power content for your Remix application.

Install a new Remix app

npx create-remix@latest cosmic-remix

Install the Cosmic JavaScript SDK

Install the Cosmic JavaScript SDK in the location of the codebase.

npm i @cosmicjs/sdk

Add an Object type in the Cosmic dashboard

Log in to the Cosmic dashboard and create a new Blog Posts Object type in a new or existing Project with the following metafields:

  1. Image: Image type with key image
  2. Content: Rich text with key content

Blog model

Add content

Add a few blog posts to get some content ready to be delivered.

Add the Blog code

In the file app/routes/_index.tsx include the following:

// app/routes/_index.tsx
import type { MetaFunction } from "@remix-run/node";
import { json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";

import { createBucketClient } from "@cosmicjs/sdk";
const cosmic = createBucketClient({
  bucketSlug: process.env.BUCKET_SLUG || "",
  readKey: process.env.BUCKET_READ_KEY || "",
});

export const meta: MetaFunction = () => {
  return [
    { title: "Cosmic Remix Blog" },
    { name: "description", content: "Welcome to Cosmic Remix!" },
  ];
};

export async function loader() {
  const { objects: posts } = await cosmic.objects
    .find({
      type: "blog-posts",
    })
    .props("title,metadata.image,metadata.content");
  return json(posts);
}

export default function Index() {
  const posts = useLoaderData<typeof loader>();
  return (
    <div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.8" }}>
      {posts?.map(
        (post: {
          title: string;
          metadata: { image: { imgix_url: string }; content: string };
        }) => {
          return (
            <div key={post.title}>
              <div>{post.title}</div>
              <div>
                <img
                  src={`${post.metadata.image.imgix_url}?w=500&auto=format,compression`}
                  alt={post.title}
                />
              </div>
              <div
                dangerouslySetInnerHTML={{ __html: post.metadata.content }}
              />
            </div>
          );
        }
      )}
    </div>
  );
}

Build and run

npx remix vite:build

Add your Cosmic API keys

In a new file titled .env add the following environment variables and make sure to switch out the values with your Cosmic API keys found in Project / API keys.

# .env
BUCKET_SLUG=add_your_bucket_slug_here
BUCKET_READ_KEY=add_your_bucket_read_key_here

Start the app

Start your app with the following command, go to http://localhost:5173, and see your blog posts.

npm run dev

Express

Follow the steps below to get started with Cosmic to power content for your Express application.

Create folder and install Express

mkdir cosmic-express
cd cosmic-express
npm init
npm i express

Install the Cosmic JavaScript SDK

Install the Cosmic JavaScript SDK in the location of the codebase.

npm i @cosmicjs/sdk

Add an Object type in the Cosmic dashboard

Log in to the Cosmic dashboard and create a new Blog Posts Object type in a new or existing Project with the following metafields:

  1. Image: Image type with key image
  2. Content: Rich text with key content

Blog model

Add content

Add a few blog posts to get some content ready to be delivered.

Create a new file app.js and add the following:

// app.js
const express = require('express');
const app = express();
const port = 3000;
import { createBucketClient } from '@cosmicjs/sdk';
const cosmic = createBucketClient({
  bucketSlug: process.env.BUCKET_SLUG || '',
  readKey: process.env.BUCKET_READ_KEY || '',
});

app.get('/', async (req, res) => {
  const { objects: posts } = await cosmic.objects
    .find({
      type: 'blog-posts',
    })
    .props('title,metadata.image,metadata.content');
  let html = '';
  posts?.map((post) => {
    html += `<div>
            <div>${post.title}</div>
            <div>
              <img
                src="${post.metadata.image.imgix_url}?w=500&auto=format,compression"
                alt="${post.title}"
              />
            </div>
            <div>${post.metadata.content}</div>
          </div>`;
  });
  res.set('Content-Type', 'text/html');
  res.send(html);
});

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});

Add your Cosmic API keys

In a new file titled .env.local add the following environment variables and make sure to switch out the values with your Cosmic API keys found in Project / API keys.

# .env.local
BUCKET_SLUG=add_your_bucket_slug_here
BUCKET_READ_KEY=add_your_bucket_read_key_here

Start the app

Start your app with the following command, go to http://localhost:3000, and see your blog posts. Note: we are using bun which enables environment variable reading without a separate package and the ability to use ES6 imports.

bun app.js

Nuxt

Follow the steps below to get started with Cosmic to power content for your Nuxt application.

Install a new Nuxt app

npx nuxi@latest init cosmic-nuxt

Install the Cosmic JavaScript SDK

Install the Cosmic JavaScript SDK in the location of the codebase.

npm i @cosmicjs/sdk

Add an Object type in the Cosmic dashboard

Log in to the Cosmic dashboard and create a new Blog Posts Object type in a new or existing Project with the following metafields:

  1. Image: Image type with key image
  2. Content: Rich text with key content

Blog model

Add content

Add a few blog posts to get some content ready to be delivered.

Add the following code to your app.vue file

<!-- // app.vue -->
<script setup lang="ts">
import { createBucketClient } from '@cosmicjs/sdk';
const cosmic = createBucketClient({
  bucketSlug: process.env.BUCKET_SLUG || '',
  readKey: process.env.BUCKET_READ_KEY || '',
});
const { objects: posts } = await cosmic.objects
  .find({
    type: 'blog-posts',
  })
  .props('title,metadata.image,metadata.content')

  function getImage(URL: string) {
    return `${URL}?w=500&auto=format,compression`
  }
</script>

<template>
  <div>
    <div v-for="post in posts" v-bind:key="post.title">
      <div>{{ post.title }}</div>
      <div>
        <img
          :src="getImage(post.metadata.image.imgix_url)"
          alt="{{ post.title }}"
        />
      </div>
      <div>{{ post.metadata.content }}</div>
    </div>
  </div>
</template>

Add your Cosmic API keys

In a new file titled .env.local add the following environment variables and make sure to switch out the values with your Cosmic API keys found in Project / API keys.

# .env.local
BUCKET_SLUG=add_your_bucket_slug_here
BUCKET_READ_KEY=add_your_bucket_read_key_here

Start the app

Start your app with the following command, go to http://localhost:3000, and see your blog posts.

npm run dev

Svelte

Follow the steps below to get started with Cosmic to power content for your Svelte application.

Install a new Svelte app

npm create svelte@latest cosmic-svelte

Answer the prompts with the following answers:

  1. Which Svelte app template? Skeleton project.
  2. Add type checking with TypeScript? Yes.
  3. Select additional options (use arrow keys/space bar) None.

Then go into your codebase and run the following commands.

cd cosmic-svelte
npm install

Install the Cosmic JavaScript SDK

Install the Cosmic JavaScript SDK in the location of the codebase.

npm i @cosmicjs/sdk

Add an Object type in the Cosmic dashboard

Log in to the Cosmic dashboard and create a new Blog Posts Object type in a new or existing Project with the following metafields:

  1. Image: Image type with key image
  2. Content: Rich text with key content

Blog model

Add content

Add a few blog posts to get some content ready to be delivered.

Create a new file at +page.server.js with the following:

// +page.server.js
/** @type {import('./$types').PageServerLoad} */
import { BUCKET_SLUG, BUCKET_READ_KEY } from '$env/static/private';
import { createBucketClient } from '@cosmicjs/sdk';
const cosmic = createBucketClient({
  bucketSlug: BUCKET_SLUG || '',
  readKey: BUCKET_READ_KEY || '',
});

export async function load() {
  const { objects: posts } = await cosmic.objects
    .find({
      type: 'blog-posts',
    })
    .props('title,metadata.image,metadata.content');
  return { posts };
}

Then add the following to the +page.svelte file:

// +page.svelte
<script>
  /** @type {import('./$types').PageData} */
  export let data;
</script>

<h1>Welcome to Cosmic Svelte</h1>
{#each data.posts as post}
  <div>{post.title}</div>
  <div>
    <img
      alt={post.title}
      src="{post.metadata.image.imgix_url}?w=500&auto=format,compression"
    />
  </div>
  <div>{@html post.metadata.content}</div>
{/each}

Add your Cosmic API keys

In a new file titled .env.local add the following environment variables and make sure to switch out the values with your Cosmic API keys found in Project / API keys.

# .env.local
BUCKET_SLUG=add_your_bucket_slug_here
BUCKET_READ_KEY=add_your_bucket_read_key_here

Start the app

Start your app with the following command, go to http://localhost:5173, and see your blog posts.

npm run dev

Fastify

Follow the steps below to get started with Cosmic to power content for your Fastify application.

Create folder and install Fastify

mkdir cosmic-fastify
cd cosmic-fastify
npm init
npm i express

Install the Cosmic JavaScript SDK

Install the Cosmic JavaScript SDK in the location of the codebase.

npm i @cosmicjs/sdk

Add an Object type in the Cosmic dashboard

Log in to the Cosmic dashboard and create a new Blog Posts Object type in a new or existing Project with the following metafields:

  1. Image: Image type with key image
  2. Content: Rich text with key content

Blog model

Add content

Add a few blog posts to get some content ready to be delivered.

Create a new file app.js and add the following:

// app.js
import Fastify from 'fastify';
const fastify = Fastify({
  logger: true,
});
import { createBucketClient } from '@cosmicjs/sdk';
const cosmic = createBucketClient({
  bucketSlug: process.env.BUCKET_SLUG || '',
  readKey: process.env.BUCKET_READ_KEY || '',
});

fastify.get('/', async (request, reply) => {
  reply.header('Content-Type', 'text/html; charset=utf-8');

  const { objects: posts } = await cosmic.objects
    .find({
      type: 'blog-posts',
    })
    .props('title,metadata.image,metadata.content');
  let html = '';
  posts?.map((post) => {
    html += `<div>
            <div>${post.title}</div>
            <div>
              <img
                src="${post.metadata.image.imgix_url}?w=500&auto=format,compression"
                alt="${post.title}"
              />
            </div>
            <div>${post.metadata.content}</div>
          </div>`;
  });
  return html;
});

const start = async () => {
  try {
    await fastify.listen({ port: 3000 });
  } catch (err) {
    fastify.log.error(err);
    process.exit(1);
  }
};
start();

Add your Cosmic API keys

In a new file titled .env.local add the following environment variables and make sure to switch out the values with your Cosmic API keys found in Project / API keys.

# .env.local
BUCKET_SLUG=add_your_bucket_slug_here
BUCKET_READ_KEY=add_your_bucket_read_key_here

Start the app

Start your app with the following command, go to http://localhost:3000, and see your blog posts. Note: we are using bun which enables environment variable reading without a separate package and the ability to use ES6 imports.

bun app.js

RedwoodJS

Follow the steps below to get started with Cosmic to power content for your RedwoodJS application.

Install RedwoodJS

yarn create redwood-app

Answer the prompts with the following answers:

  1. Where would you like to create your Redwood app? cosmic-redwood
  2. Select your preferred language. TypeScript
cd cosmic-redwood
yarn install

Start the app.

yarn rw dev

Create the Blog home page.

yarn redwood generate page home /

Go into the web/src folder.

cd web/src

Install the Cosmic JavaScript SDK

Install the Cosmic JavaScript SDK in the location of the codebase.

npm i @cosmicjs/sdk

Add an Object type in the Cosmic dashboard

Log in to the Cosmic dashboard and create a new Blog Posts Object type in a new or existing Project with the following metafields:

  1. Image: Image type with key image
  2. Content: Rich text with key content

Blog model

Add content

Add a few blog posts to get some content ready to be delivered.

In the file web/src/pages/HomePage/HomePage.tsx add the following:

// web/src/pages/HomePage/HomePage.tsx
import { createBucketClient } from '@cosmicjs/sdk';

import { Metadata } from '@redwoodjs/web';

// app/page.tsx
const cosmic = createBucketClient({
  bucketSlug: process.env.REDWOOD_ENV_BUCKET_SLUG || '',
  readKey: process.env.REDWOOD_ENV_BUCKET_READ_KEY || '',
});

const { objects: posts } = await cosmic.objects
  .find({
    type: 'blog-posts',
  })
  .props('title,metadata.image,metadata.content');

const HomePage = () => {
  return (
    <>
      <Metadata title="Blog" description="Blog home page" />
      <h1>Blog</h1>
      {posts?.map(
        (post: {
          title: string;
          metadata: { image: { imgix_url: string }; content: string };
        }) => {
          return (
            <div key={post.title}>
              <div>{post.title}</div>
              <div>
                <img
                  src={`${post.metadata.image.imgix_url}?w=500&auto=format,compression`}
                  alt={post.title}
                />
              </div>
              <div
                dangerouslySetInnerHTML={{ __html: post.metadata.content }}
              />
            </div>
          );
        }
      )}
    </>
  );
};

export default HomePage;

Add your Cosmic API keys

In the existing file titled .env add the following environment variables and make sure to switch out the values with your Cosmic API keys found in Project / API keys.

# .env
REDWOOD_ENV_BUCKET_SLUG=add_your_bucket_slug_here
REDWOOD_ENV_BUCKET_READ_KEY=add_your_bucket_read_key_here

Restart the app

Restart your app with the following command:

yarn rw dev

Vite

Follow the steps below to get started with Cosmic to power content for your Vite application.

Install a new Vite app

npm create vite@latest

Answer the prompts with the following answers:

  1. Project name. cosmic-vite
  2. Select a framework. React
  3. Select a variant. TypeScript

Now run:

cd vite-project
npm install

Install the Cosmic JavaScript SDK

Install the Cosmic JavaScript SDK in the location of the codebase.

npm i @cosmicjs/sdk

Add an Object type in the Cosmic dashboard

Log in to the Cosmic dashboard and create a new Blog Posts Object type in a new or existing Project with the following metafields:

  1. Image: Image type with key image
  2. Content: Rich text with key content

Blog model

Add content

Add a few blog posts to get some content ready to be delivered.

Add the following code to your src/App.tsx file

// src/App.tsx
import { useState, useEffect } from "react";
import { createBucketClient } from "@cosmicjs/sdk";
const cosmic = createBucketClient({
  bucketSlug: import.meta.env.VITE_BUCKET_SLUG || "",
  readKey: import.meta.env.VITE_BUCKET_READ_KEY || "",
});

async function getPosts() {
  const { objects: posts } = await cosmic.objects
    .find({
      type: "blog-posts",
    })
    .props("title,metadata.image,metadata.content");
  return posts;
}

type PostType = {
  title: string;
  metadata: { image: { imgix_url: string }; content: string };
};

function App() {
  const [posts, setPosts] = useState<PostType[]>([]);
  useEffect(() => {
    getPosts().then((data) => setPosts(data));
  }, []);
  return (
    <>
      {posts.length &&
        posts?.map((post: PostType) => {
          return (
            <div key={post.title}>
              <div>{post.title}</div>
              <div>
                <img
                  src={`${post.metadata.image.imgix_url}?w=500&auto=format,compression`}
                  alt={post.title}
                />
              </div>
              <div
                dangerouslySetInnerHTML={{ __html: post.metadata.content }}
              />
            </div>
          );
        })}
    </>
  );
}

export default App;

Add your Cosmic API keys

In a new file titled .env.local add the following environment variables and make sure to switch out the values with your Cosmic API keys found in Project / API keys.

# .env.local
VITE_BUCKET_SLUG=add_your_bucket_slug_here
VITE_BUCKET_READ_KEY=add_your_bucket_read_key_here

Start the app

Start your app with the following command, go to http://localhost:5173, and see your blog posts.

npm run dev

Hono

Follow the steps below to get started with Cosmic to power content for your Hono application.

Install a new Hono app

npm create hono@latest

Answer the prompts with the following answers:

  1. Target directory. cosmic-hono
  2. Which template do you want to use? bun
  3. Do you want to install project dependencies? yes
  4. Which package manager do you want to use? npm

Now run:

cd cosmic-hono

Install the Cosmic JavaScript SDK

Install the Cosmic JavaScript SDK in the location of the codebase.

npm i @cosmicjs/sdk

Add an Object type in the Cosmic dashboard

Log in to the Cosmic dashboard and create a new Blog Posts Object type in a new or existing Project with the following metafields:

  1. Image: Image type with key image
  2. Content: Rich text with key content

Blog model

Add content

Add a few blog posts to get some content ready to be delivered.

Change the default src/index.ts to a JSX file src/index.tsx and add the following code

// src/index.tsx
import { Hono } from 'hono';
import { raw } from 'hono/html';
import { createBucketClient } from '@cosmicjs/sdk';
const cosmic = createBucketClient({
  bucketSlug: process.env.BUCKET_SLUG || '',
  readKey: process.env.BUCKET_READ_KEY || '',
});

const app = new Hono();
type PostType = {
  title: string,
  metadata: { image: { imgix_url: string }, content: string },
};

app.get('/', async (c) => {
  const { objects: posts } = await cosmic.objects
    .find({
      type: 'blog-posts',
    })
    .props('title,metadata.image,metadata.content');
  const html = posts?.map((post: PostType) => {
    return (
      <div>
        <div>{post.title}</div>
        <div>
          <img
            src={`${post.metadata.image.imgix_url}?w=500&auto=format,compression`}
            alt={`${post.title}`}
          />
        </div>
        <div>{raw(post.metadata.content)}</div>
      </div>
    );
  });
  return c.html(html);
});

export default app;

Change the default start script in package.json to accept the new file name

// package.json
"scripts": {
  "dev": "bun run --hot src/index.tsx"
}

Add your Cosmic API keys

In a new file titled .env.local add the following environment variables and make sure to switch out the values with your Cosmic API keys found in Project / API keys.

# .env.local
BUCKET_SLUG=add_your_bucket_slug_here
BUCKET_READ_KEY=add_your_bucket_read_key_here

Start the app

Start your app with the following command, go to http://localhost:3000, and see your blog posts.

npm run dev

Bun

Follow the steps below to get started with Cosmic to power content for your Bun application.

Create folder and install Bun and React Dom

mkdir cosmic-bun
cd cosmic-bun
npm init
npm i bun -g
npm i react-dom

Install the Cosmic JavaScript SDK

Install the Cosmic JavaScript SDK in the location of the codebase.

npm i @cosmicjs/sdk

Add an Object type in the Cosmic dashboard

Log in to the Cosmic dashboard and create a new Blog Posts Object type in a new or existing Project with the following metafields:

  1. Image: Image type with key image
  2. Content: Rich text with key content

Blog model

Add content

Add a few blog posts to get some content ready to be delivered.

Create a new file index.tsx and add the following:

// index.tsx
import { renderToReadableStream } from 'react-dom/server';
import { createBucketClient } from '@cosmicjs/sdk';

const cosmic = createBucketClient({
  bucketSlug: process.env.BUCKET_SLUG || '',
  readKey: process.env.BUCKET_READ_KEY || '',
});

type PostType = {
  title: string,
  metadata: { image: { imgix_url: string }, content: string },
};

function Home({ posts }: { posts: PostType[] }) {
  return (
    <>
      {posts?.map((post: PostType) => {
        return (
          <div key={post.title}>
            <div>{post.title}</div>
            <div>
              <img
                src={`${post.metadata.image.imgix_url}?w=500&auto=format,compression`}
                alt={post.title}
              />
            </div>
            <div dangerouslySetInnerHTML={{ __html: post.metadata.content }} />
          </div>
        );
      })}
    </>
  );
}

const server = Bun.serve({
  port: 3000,
  async fetch(req) {
    const { objects: posts } = await cosmic.objects
      .find({
        type: 'blog-posts',
      })
      .props('title,metadata.image,metadata.content');
    const stream = await renderToReadableStream(<Home posts={posts} />);
    return new Response(stream, {
      headers: { 'Content-Type': 'text/html' },
    });
  },
});

console.log(`Listening on ${server.url}`);

Add your Cosmic API keys

In a new file titled .env.local add the following environment variables and make sure to switch out the values with your Cosmic API keys found in Project / API keys.

# .env.local
BUCKET_SLUG=add_your_bucket_slug_here
BUCKET_READ_KEY=add_your_bucket_read_key_here

Start the app

Start your app with the following command, go to http://localhost:3000, and see your blog posts. Note: we are using bun which enables environment variable reading without a separate package and the ability to use ES6 imports.

bun index.tsx