DEV Community

Cover image for Bun
Agus Sudarmanto
Agus Sudarmanto

Posted on

Bun

Wait, what is Bun

Bun is a java script runtime that is designed to be fast and efficient. It is built on top of the JavaScriptCore engine and uses a number of optimizations, advantages of using the low-level language Zig to make it faster.

Install Bun and init

curl -fsSL https://bun.sh/install | bash
bun init
Enter fullscreen mode Exit fullscreen mode

Experiment with Elysia (Bun Framework)

Elysia is ergonomic Framework for Humans, TypeScript with End-to-End Type Safety, unified type system and outstanding developer experience. Supercharged by Bun.

Preparation:

  1. Install packages
  2. Configure knex
  3. Configure database
  4. Configure environment
  5. Create migration file and run it
  6. Create controller
  7. Run server
  8. Using docker

# 1. Install packages

bun add elysia knex dotenv pg
knex init
Enter fullscreen mode Exit fullscreen mode

# 2. Configure knex

// -- knexfile.js
require("dotenv").config();

export const development = {
  client: "pg",
  connection: process.env.DATABASE_URL,
  migrations: {
    directory: "./db/migrations",
  }
};
Enter fullscreen mode Exit fullscreen mode

# 3. Configure database

// -- db.js 
const knex = require("knex");
const knexFile = require("./knexfile.js");

const environment = process.env.NODE_ENV || "development";

export default knex(knexFile[environment]);
Enter fullscreen mode Exit fullscreen mode

# 4. Configure environment

// -- .env
DATABASE_URL = <YOUR_DATABASE_URI>
Enter fullscreen mode Exit fullscreen mode

# 5. Create migration file and run it

run knex migrate:make blog

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
export function up (knex) {
  return knex.schema.createTable("blog", (table) => {
    table.increments("id").primary();
    table.string("title").notNullable();
    table.string("content").notNullable();
    table.string("author").notNullable();
    table.timestamp("created_at").defaultTo(knex.fn.now());
  });
}

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
export function down (knex) {
  return knex.schema.dropTable("blog");
}
Enter fullscreen mode Exit fullscreen mode

After creating migration table, run knex migrate:latest

# 6. Create controller

// -- index.ts
const { Elysia } = require("elysia");
let db = require("./db");
db = db.default;
const app = new Elysia();

// -- New post
app.post("/posts/create-new-post", async (context) => {
  try {
    //Extract the title, content and author from the request body
    const { title, content, author } = context.body;

    //Insert the post into the database
    const post = await db("blog").insert({
      title,
      content,
      author,
    });

    //Send response to the client
    return new Response(JSON.stringify(post));
  } catch (error: any) {
    //Send error to the client
    return new Response(error.message, { status: 500 });
  }
});

// -- Get all posts
app.get("/posts", async (context) => {
  try {
    //Get all posts from the database
    const posts = await db.select("*").from("blog");

    //Send response to the client
    return new Response(JSON.stringify(posts));
  } catch (error: any) {
    //Send error to the client
    return new Response(error.message, { status: 500 });
  }
});

// -- Get post by ids
app.get("/posts/:id", async (context) => {
  //Extract the id from the request params
  const { id } = context.params;

  //Get the post from the database
  const post = await db("blog").where({ id });

  //If the post is not found, send a 404 response
  if (post.length === 0) {
    return new Response("Post not found", { status: 404 });
  }

  //Send response to the client
  return new Response(JSON.stringify(post));
});

// -- Update post
app.patch("/posts/:id/update-post", async (context) => {
  //Extract the id from the request params
  const { id } = context.params;

  //Extract the title and content from the request body
  const { title, content } = context.body;

  //Update the post in the database
  const post = await db("blog").where({ id }).update(
    {
      title,
      content,
    },
    ["id", "title", "content"]
  );

  //Send response to the client
  return new Response(JSON.stringify(post));
});

// -- Delete post
app.delete("/posts/:id/delete-post", async (context) => {
  //Extract the id from the request params
  const { id } = context.params;

  //Delete the post from the database
  const post = await db("blog").where({ id }).del();

  //Send response to the client
  return new Response(JSON.stringify(post));
});

app.listen(3000, () => {
  console.log("Server running on port 3000");
});
Enter fullscreen mode Exit fullscreen mode

# 7. Run server

Then run bun --watch index.ts

# 8. Using Docker

run touch Dockerfile

FROM oven/bun

WORKDIR /app

COPY package.json .
COPY bun.lockb .

RUN bun install

COPY . .

EXPOSE 3000

CMD ["bun", "index.ts"]
Enter fullscreen mode Exit fullscreen mode

Top comments (0)