# baidu/san: a JavaScript component framework with its own template compiler

> San is Baidu's MVVM component framework, published to npm as san and shipped with a template syntax, a TypeScript type package and a set of companion libraries. It is a reasonable fit if you want a small runtime and are willing to adopt a non-mainstream ecosystem.

**baidu/san** — A fast, portable, flexible JavaScript component framework

- Repository: https://github.com/baidu/san
- Website: https://baidu.github.io/san/
- Stars: 4,736 · Forks: 537
- Language: JavaScript
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/baidu-san

## What san is for, and who ends up using it

San is described in its README as a fast, portable, flexible JavaScript component framework. The description is accurate in a narrow sense: it is a component framework in the MVVM style, where a component declares a template and a data object, and the framework keeps the rendered DOM in sync when that data changes. The quick start example shows exactly this shape. A component is created with san.defineComponent, given a template string, and attached to a DOM node with myApp.attach(document.body).

The intended user is a frontend engineer building a single-page or multi-page application who wants the component model without the full weight of a mainstream framework. The companion table in the README is the clearest signal of scope: san-router for hash and html5 mode routing, san-store for application state, san-update for immutable object updates, san-composition for a composition API, san-ssr for server-side rendering, and three component libraries (santd, san-mui, san-xui) covering Ant Design, Material Design and Baidu Cloud Console styling. That is a complete application stack, assembled from separate packages rather than bundled into one dependency.

Where san is the wrong tool is equally clear from that table. If you need a component library with thousands of community-contributed widgets, or you are hiring and want candidates who already know the framework, san is a poor bet. The surrounding ecosystem is maintained under the Baidu and ecomfe GitHub organizations, not by an open marketplace.

## The mechanism: defineComponent, templates, and two-way binding

San does not use a virtual DOM in the React sense. The repository contains a doc/anode.md file and a doc/anode-pack.md file, and the README links to both under the name ANode. The companion list also includes san-anode-utils, described as util functions for ANode. ANode appears to be san's own representation of the component tree, and APack its packaging format, but the README itself does not explain the runtime model. Anyone evaluating san for a performance-sensitive application should read those two documents rather than assume the rendering strategy.

The template syntax is visible in the quick start. Inside a template string, {{name}} interpolates a value, and value="{=name=}" creates a two-way binding between the input element and the component's data. That binding syntax is the part of san that most distinguishes it from React, where the equivalent requires an onChange handler and a controlled value. The data object passed to the constructor seeds the component state, and the framework re-renders the affected part of the DOM when that state changes.

The dist directory and the package.json fields confirm how the framework is delivered. The main and browser fields both point at dist/index.js, the unpkg field points at dist/san.min.js, and the package.json size script references dist/san.spa.modern.min.js. That last filename suggests a modern-browser SPA build exists alongside the general one, though the README does not document the difference between the dist files; it links to a separate Dist Files Information page for that.

## Installing san and rendering a first component

The README gives two installation paths. The npm path is a single command, and it installs the package under the name san.

```bash
npm i san
```

After that, the package resolves through dist/index.js, and the types field points at the types directory, so TypeScript projects pick up the bundled declarations without an extra @types package. The second path skips the build step entirely and loads the framework from a CDN.

```html
<script src="https://unpkg.com/san@latest"></script>
```

With the script tag in place, the quick start in the README is a complete working page. The component below declares a template with one input and one paragraph, then attaches itself to the document body. The {=name=} syntax binds the input's value to the name field in both directions, so typing in the box updates the paragraph without any handler code.

```html
<script>
const MyApp = san.defineComponent({
    template: `
        <div>
            <input type="text" value="{=name=}">
            <p>Hello {{name}}!</p>
        </div>
    `
});

let myApp = new MyApp({
    data: {
        name: 'San'
    }
});
myApp.attach(document.body);
</script>
```

What you should see is a text input pre-filled with the string San and a paragraph reading Hello San!. The README also points to two runnable Todos examples in the repository, one AMD and one ESNext, plus a RealWorld app built with san-store, which is the better starting point if you want to see how the pieces fit together before committing.

## Where san gets awkward: documentation gaps and build assumptions

The README is a landing page, not a manual. It links to a tutorial, an API reference and the two ANode documents, and it lists fifteen companion packages, but it explains almost none of the runtime behaviour itself. That is a normal arrangement for a mature project, and it means the evaluation cost sits in the linked documentation rather than in the README. If you are comparing frameworks on a deadline, budget time for reading the tutorial and the API pages before you can judge whether san fits.

The build story is a second friction point. The dev script runs node ./tool/dev.js, the build script runs node ./tool/build.js, and the test pipeline is not a single command: pretest runs the build, then a hydrate test builder, then a spec builder, before test:unit starts Karma. The unit tests run in a real browser through Karma, and the end-to-end tests run through WebdriverIO, with a separate test:sauce script that fans out across modern, ie_family and mobile browser groups. That is a heavier contributor setup than a framework whose tests run in Node, and it matters if you intend to patch san itself rather than only consume it.

Finally, the template is a JavaScript string in the quick start. The README's companion table lists san-loader as a Webpack loader for single-file components, and san-cli as a CLI for scaffolding, but neither is part of the core package. Nothing in the README states that a build step is required, and the CDN example proves it is not, so the honest summary is that san works without tooling and the tooling lives in separate repositories.

## How san compares with Vue, and when the difference matters

The closest point of comparison is Vue. Both are MVVM component frameworks with template strings, both support two-way binding through a dedicated attribute syntax, and both ship an official router, a state-management package and an SSR package as separate installs. A developer moving from Vue to san will recognise the component shape quickly. The difference is in adoption: Vue's ecosystem includes a large third-party component market and a deep pool of engineers who already know it, while san's components come from the santd, san-mui and san-xui libraries listed in the README, all maintained inside the same organizations.

That difference cuts both ways. A smaller ecosystem means fewer abandoned dependencies and a more predictable surface, since every package in the table is under Baidu or ecomfe control. It also means you cannot assume a widget exists for an unusual requirement; you write it. For an internal admin console or a product where the team controls the whole stack, that trade is often acceptable. For a public-facing product where the roadmap depends on third-party integrations, it is a real constraint.

The second comparison worth making is against the SSR story. San has san-ssr, described as an SSR framework and tool library, and the repository's test pipeline includes a hydrate test builder, which indicates hydration is exercised in CI. Vue offers SSR through Nuxt and a documented server-renderer. Both require you to keep server and client template rendering consistent, and neither removes that work. San's advantage here is only that san-ssr is listed as a first-party companion rather than a community layer.

## Maintenance, licence and the cost of staying current

The repository is not archived, and the last push was on 2026-07-15. The most recent release listed is 3.15.5 from 2026-01-01, preceded by 3.15.4 on 2025-11-12 and 3.15.3 on 2025-08-31. The package.json in the repository carries version 3.15.6, which is ahead of the newest entry in the release list, so the published tag and the repository manifest were not in step at the time those facts were recorded. That gap is worth checking before you pin a version, because it affects whether the source you read matches the artifact you install.

Release notes are not part of the README. The changelog section says only: please visit document ChangeLog, linking to CHANGELOG.md. There is no stated support policy, no long-term-support branch and no documented deprecation window in the README. For a team that needs to plan upgrades around a vendor commitment, that absence is the main maintenance risk, and it is a documentation gap rather than a sign of abandonment.

The licence is MIT, stated in the README and in the package.json license field, with a LICENSE file at the repository root. MIT permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is a permissive arrangement with no copyleft obligation, but it is not legal advice and the terms that apply to the companion packages should be checked separately, since each lives in its own repository. The README does not state the licences of san-router, san-store, san-ssr or the component libraries.

## Conclusion

Adopt san if you want a compact MVVM framework with an npm package, TypeScript typings and companion libraries for routing, state and SSR, and you accept that the ecosystem is smaller than React's or Vue's. Do not adopt it if your team needs a large hiring pool, a broad third-party component market, or a framework whose release cadence you can predict from a public roadmap; the CHANGELOG is the only release record the README points to. Before committing, verify three things: that the version you install from npm matches the dist files you plan to serve, that san-ssr handles the templates you actually write, and that the last push date on the repository is recent enough for your maintenance policy.

## FAQ

### How do I install san?

Install it from npm with npm i san, or load it in a page from the CDN with a script tag pointing at https://unpkg.com/san@latest. The npm package resolves through dist/index.js and includes TypeScript declarations in the types directory.

### Does san include a router and state management?

Not in the core package. The README lists san-router for hash and html5 mode routing and san-store for application state as separate companion packages, alongside san-update for immutable object updates and san-ssr for server-side rendering.

### What licence does san use?

San is MIT licensed, stated in the README and in the license field of package.json, with a LICENSE file at the repository root. The README does not state the licences of the companion packages, which live in separate repositories.

## Sources

- [baidu/san on GitHub](https://github.com/baidu/san)
- [License: MIT](https://github.com/baidu/san/blob/master/LICENSE)
- [Project website](https://baidu.github.io/san/)
- [README](https://github.com/baidu/san/blob/master/README.md)
- [Releases](https://github.com/baidu/san/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/baidu-san
