Welcome to Vixeny!

We’re happy to have you exploring our framework!. Vixeny is all about making web development straightforward and enjoyable, no matter your background in coding. Whether you’re just starting out or looking to shift into a new style of programming, we’ve designed Vixeny to be as welcoming as possible.

So, What’s this project?

An ecosystem of functional web tools, that aims to make code more:

  • Open: All our tools are exportable and can be used in other project.

  • Reusable: Make it once and use it again, every element can be reused and composed in many ways.

  • Testable: Thanks to its monolithic structure, it can be tested at any state.

  • Smart: Asyncronless with an integrated system that helps you to detect bugs and optimize your code on the fly.

  • Safe and maintainable: Everything is deterministic, and its object-based structure allows the maintainers to easily add things without needing to push broken code changes.

  • Fast: Fastest framework when it comes to Request -> Response handlers in not only Deno but also Bun.

How?

Don’t sweat the fancy “functional programming” stuff. Vixeny is made to be friendly for everyone. Our guides are split into simple levels, so you only pick up what you actually need, step by step.

Why Vixeny?

It got its name because it’s like a coding style that’s easy to learn and still super rewarding. It helps you see everything clearly at any point.

You can copy, paste, and run all the examples. There’s an example for everything!

Now, let’s go from zero to hero with Vixeny!

Quick start

Designed to be backward compatible and runtime agnostic, ensures that code you write today will continue to work seamlessly in the future, whether you’re using Deno or Bun.

Ready to start? Just run these commands to install our templates:

Petitions

Routes are called petitions. A petition is just an object with a path and a function f that does something when someone visits that path. Here’s a simple example:

import { petitions } from "vixeny";

// Returning a `BodyInit`
const helloWorld = petitions.add()({
  path: "/hello",
  f: () => "hello World!",
});

// Returning a `Response`
const ping = petitions.add()({
  path: "/ping",
  f: () => new Response("pong"),
});

console.log(helloWorld);

Notice that even if you specify only path and f, the log output is:

{
  path: "/hello",
  f: [Function: f],
  type: "base",
  o: undefined,
  ... // More in the future
}

Vixeny’s architecture ensures that all petitions work across different versions right out of the box!

Reusability

Vixeny also offers two special petitions, resolve and branch, which we’ll show you later. For now, here’s a quick look at what you can do:

import { petitions } from "vixeny";

// Using `resolve`
const sayHello = petitions.resolve()({
  f: () => "hello",
});

const hey = petitions.add()({
  path: "/hey",
  resolve: {
    // Adding `sayHello` function
    sayHello,
  },
  // Resolving in context
  f: ({ resolve }) => `${resolve.sayHello} World!`,
});

In practice, you’ll rarely need to manually declare petitions like this, that’s why we have wrap

Wrap

The wrap function helps you work with petitions without hassle. With wrap, you can:

  • Keep things clean and avoid side effects.
  • Test petitions without starting a server.
  • Debug easily.
  • Deploy quickly.
  • And much more!
import { wrap } from "vixeny";

const root = wrap()()
  .get({
    path: "/ping",
    f: () => "pong",
  })
  .post({
    path: "/ping",
    f: () => "pong",
  })
  .delete({
    path: "/ping",
    f: () => "pong",
  });

Testing

You can test everything without running a server and even mock parts of your code to try out different scenarios.

import { wrap } from "vixeny";

const handler = wrap()()
  .get({
    path: "/helloWorld",
    f: () => "helloWorld",
  })

// Making a testable unit
const testHandler = await handler.testPetitions();

// "helloWorld"
await testHandler("/helloWorld")
  .then(async (response) => await response.text())
  .then(console.log)

Mocking

Supports testing individual petitions by injecting values while preserving their structure:

import { petitions, wrap } from "vixeny";

const lotery = petitions.resolve()({
  // Generates a random number from 0 to 10000
  f:  () => Math.round(10000)
});

const routes = wrap()().get({
  path: "/winAPrice",
  resolve: { lotery },
  f: ({ resolve }) =>
    resolve.lotery 
      ? 'Winner!'
      : 'Try again',
});

// Inject the mocked resolve
const mockRoutes = await routes.handleRequest("/winAPrice")({
  resolve: {
    lotery: { f: () => 10000 },
  },
});

// Always a winner
await mockRoutes("/winAPrice")
  .then(async (res) => await res.text())
  .then(console.log)

Vixeny is fully typed, so you get tooltips and hints right in your editor.

Keyboard mode

Do you like to use your keyboard? Here some tips:

Shortcut Action
Shift + S Focus search bar
Shift + A Focus first element
Shift + Z Zen mode
Shift + L Light / Dark mode
Tab Jump faster!

Guides

Want to learn more? We’ve got guides to help you with everything:

Thanks for stopping by!