Introducing ofa.js: A Lightweight Front‑End Framework for Easy Component Development

The article presents ofa.js, a new front‑end framework that eliminates the need for Node/npm/webpack workflows, allowing developers to quickly create and package components, use template syntax sugar, achieve seamless state synchronization, and build full web applications with minimal setup.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Introducing ofa.js: A Lightweight Front‑End Framework for Easy Component Development

Recently a new front‑end framework called ofa.js has emerged. Unlike traditional workflows that rely on Node, npm, and webpack, ofa.js can be used by simply adding a script tag, enabling developers to build large applications with the same ease as React, Vue, or Angular.

Extremely Easy to Get Started

If you want to use a component such as Ant Design's Button, you normally need to learn Node.js, npm, and React. With ofa.js you only need basic HTML knowledge. The following example shows how to import ofa.js and use the official punch-logo component:

<!-- 引入ofa.js到您的项目 -->
<script src="https://cdn.jsdelivr.net/gh/kirakiray/ofa.js/dist/ofa.min.js"></script>

<!-- 加载预先开发的punch-logo组件 -->
<l-m src="https://kirakiray.github.io/ofa-v4-docs/docs/publics/comps/punch-logo.html"></l-m>

<!-- 使用punch-logo组件 -->
<punch-logo style="margin:50px 0 0 100px;">
    <img src="https://kirakiray.github.io/ofa-v4-docs/docs/publics/logo.svg" logo height="90"/>
    <h2>不加班了</h2>
    <p slot="fly">下班给我</p>
    <p slot="fly">迟点下班</p>
    <p slot="fly">周末加班</p>
</punch-logo>

You can copy the above code into a blank HTML file and run it directly, which demonstrates how ofa.js integrates smoothly with traditional web stacks.

One‑Step Component Packaging

Packaging a component is equally simple; a single HTML file is enough. Below is an official switch component example:

<!-- my-switch.html -->
<template component>
  <style>
    .switch {
      position: relative;
      display: inline-block;
      width: 60px;
      height: 34px;
      background-color: #ccc;
      transition: background-color 0.4s;
      border-radius: 34px;
      cursor: pointer;
    }
    .slider {
      position: absolute;
      height: 26px;
      width: 26px;
      left: 4px;
      bottom: 4px;
      background-color: white;
      transition: transform 0.4s;
      border-radius: 50%;
    }
    .switch.checked { background-color: #2196f3; }
    .switch.checked .slider { transform: translateX(26px); }
  </style>
  <div class="switch" class:checked="checked" on:click="checked = !checked">
    <span class="slider"></span>
  </div>
  <script>
    export default {
      tag: "my-switch",
      data: { checked: true },
    };
  </script>
</template>

To use it, reference the component with the l-m tag:

<script src="https://cdn.jsdelivr.net/gh/kirakiray/ofa.js/dist/ofa.min.js"></script>
<l-m src="./my-switch.html"></l-m>
<my-switch></my-switch>

Rich Template Syntax Sugar

ofa.js offers many Vue‑like template syntactic sugars, including text rendering, attribute binding, two‑way binding, event binding, conditional rendering, list rendering, and more.

Built‑In State Synchronization

Unlike other frameworks, ofa.js provides seamless, “no‑feeling” state synchronization. Data objects are automatically kept in sync without explicit function calls. The following example demonstrates a shared dark‑mode toggle:

// is-dark.js
const isDark = $.stanz({ value: false });
export default isDark;
<!-- my-button.html -->
<template component>
  <style>
    :host { display: block; }
    .container { display: inline-block; padding: 0.5em 1em; color: white; border-radius: 6px; background-color: blue; cursor: pointer; user-select: none; }
    .container.dark { background-color: red; }
  </style>
  <div class="container" class:dark="isDark.value"><slot></slot></div>
  <script>
    import isDark from "./is-dark.js";
    export default {
      data: { isDark: {} },
      attached() { this.isDark = isDark; },
      detached() { this.isDark = {}; }
    };
  </script>
</template>

Simple Form Operations

Forms can be bound to a data object using the formData method, which provides automatic two‑way synchronization. Example:

<!-- form example -->
<form id="myForm">
  <input type="text" name="username" value="John Doe"/>
  <div>
    sex:
    <label>man <input type="radio" name="sex" value="man"/></label>
    <label>woman <input type="radio" name="sex" value="woman"/></label>
  </div>
  <textarea name="message">Hello World!</textarea>
</form>
<div id="logger"></div>
<script>
  const data = $("#myForm").formData();
  $("#logger").text = data;
  data.watch(() => { $("#logger").text = data; });
</script>

Data can also be set programmatically, which updates the form instantly:

<!-- reverse set -->
<script>
  const data = $("#myForm").formData();
  setTimeout(() => {
    data.username = "Yao";
    data.sex = "man";
    data.message = "ofa.js is good!";
  }, 1000);
</script>

Developing Full Applications

ofa.js can be used to build complete web applications that are embedded via the o-app component. A minimal HTML entry looks like this:

<!-- app demo -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>Application Demo</title>
  <script src="https://cdn.jsdelivr.net/gh/kirakiray/ofa.js/dist/ofa.min.js"></script>
</head>
<body>
  <o-app src="https://xxxxx.com/app-config.mjs"></o-app>
</body>
</html>

SCSR (Static Client‑Side Rendering)

The framework also provides a static client‑side rendering solution that retains the interactivity of CSR while allowing pages to be crawled by search engines.

Compact Code Size

The current version 4.3.29 of ofa.min.js is only 52 KB (18 KB gzipped), making it very lightweight.

Other Notes

The library has recently been upgraded to version 4, with a limited set of third‑party plugins that will be expanded over time. The author is preparing a UI library based on ofa.js.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Web Developmentfrontend frameworkstate synchronizationcomponent developmentofa.js
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.