One script tag, no models: how live2d-widget actually loads
Bring a cute mascot home | Live2D widget for web platforms.
At a glance
- What is it?
- live2d-widget puts a Live2D character on any web page through autoload.js and a single script line. The code is small and the configuration surface is small, but the repository ships no models, keeps its own Cubism core paths, and ships tip text that the site owner is expected to audit before deploying.
- Who is it for?
- live2d-widget suits a blog owner who wants a Live2D character on a page in one line and is prepared to point cdnPath at a model repository and edit waifu-tips.json by hand. It does not suit a commercial site, since the README limits the displayed models to research and study, or a workplace page, since it warns that the shipped tip text may not be suitable to read at work.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- stevenjoezhang/live2d-widget11,029 ★ · +61
| Repository | 2026-09-22 | 2026-11-14 |
|---|---|---|
| stevenjoezhang/live2d-widget | 11k | 11k |
61 Stars in the last 53 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
One script tag brings in autoload.js, waifu.css and a Cubism core
A blog owner adds the character by pasting a single line into the head or body of an HTML page:
<script src="https://fastly.jsdelivr.net/npm/[email protected]/dist/autoload.js"></script>That line is the entire installation for anyone who does not want to configure anything, and the widget it produces is built from files you never see. autoload.js pulls in two of them, waifu.css and waifu-tips.js, and waifu-tips.js is where the initWidget function is created. initWidget is the main entry point that puts the character on screen, and it takes one plain object.
Every path in that object is a remote URL. waifuPath points at the tips file, cdnPath at the model repository, and two separate options carry the runtime itself: cubism2Path for Cubism 2 Core and cubism5Path for Cubism 5 Core, whose default sits on live2d.com rather than on a CDN the project controls. Only one core loads, chosen from the version detected in the model, which is how a single dist file serves both Cubism 2 and Cubism 3 or newer models while staying smaller. TypeScript is the primary language, and the one runtime dependency in package.json is @fortawesome/fontawesome-free 7.2.0.
No model ships with the repository, so cdnPath carries the payload
A fresh clone of stevenjoezhang/live2d-widget contains no character. The repository holds code, a stylesheet and a tips file, and the modelId option defaults to 0, which selects whatever the configured repository lists first. Where that character comes from is cdnPath, and its default value is https://fastly.jsdelivr.net/gh/fghrsh/live2d_api/, a model repository maintained by somebody else. Anyone who pastes the script tag and stops there is displaying a model they did not choose, served from a path they did not set.
The choice has a second edge. The repository states that the models, images and motion data it displays belong to their original authors, are there for research and study, and must not be used commercially. The widget's own code is GPL-3.0, and the README points to other model repositories such as zenghongtu/live2d-model-assets, but it does not document a way to check the licensing of a model before you put it in front of readers. On a site that sells anything, that check is the first piece of work, and it happens outside this repository.
The apiPath backend went away in 1.0 and left model_list.json behind
Tutorials written for the older initWidget talk about an apiPath option and a backend you host yourself, with fghrsh/live2d_api named as the reference implementation to copy. That route is closed. From version 1.0 the work moved to the front end, and every model resource can be served statically instead.
The consequence is concrete rather than philosophical. Change requests such as dress-up now work as long as two things exist on whatever host serves the models: a model_list.json describing what is available, and a textures.cache for each model. No request reaches your own server, which is the cheapest deployment in the whole project. It is also where pre-1.0 guides go wrong: you end up looking for an apiPath key that initWidget no longer reads and a server with nothing left to serve.
For a different approach the README points to guansss/pixi-live2d-display on the web, and it groups TSKI433/hime-display, zenghongtu/PPet and LikeNeko/L2dPetForMac as desktop versions, which put the same kind of model in an application window instead of a page.
showToggleAfterQuit: false leaves no way back until storage is cleared
One option has a lasting effect on the page. showToggleAfterQuit defaults to true, so clicking the close control hides the character and leaves a small button that brings it back. Set it to false and that button is not rendered, which the README describes as a permanent shutdown until local storage is cleared.
The consequence for a reader is easy to miss while you are testing. Click close once, and a visitor who then finds no way to get the character back has to clear storage for your origin themselves. No option reverses the state on the next page view, and the fix lives in the browser rather than in your site. Leave the default on for any site with an audience that will click by accident, and treat false as a decision for a specific group of visitors.
logLevel is the other handle worth knowing. It takes error, warn, info or trace, and defaults to error, so a widget that renders badly tells you nothing until you raise it.
waifu-tips.json arrives with Hexo NexT selectors and text you must review
Most of what the character says comes from waifu-tips.json, which pairs a CSS selector with the text shown when something matches it. The shipped selectors are written for the Hexo NexT theme. On any other site the lines that should trigger a message may never fire, and a selector that matches too broadly speaks in places you did not choose, so editing this file is part of setting the widget up rather than an optional extra.
The text deserves the same attention. The README warns that the shipped content may not suit every age group and may not be suitable to read at work, and it leaves suitability to you. That warning lands hardest on a company blog or a school site, and the shipped file is what a fresh install displays.
The tools are the other half of what appears on screen. The paper-plane button opens a small asteroid game credited to WebsiteAsteroids, and the sentence button draws lines from the hitokoto API. Both live in the tools array whose default is set in autoload.js rather than in the options table, so removing them means passing your own array to initWidget.
PJAX and template engines decide where the script tag can go
Placement is treated carefully here. Where the line goes depends on how the site is built: with Hexo you edit the theme template rather than a generated page, and other template engines work the same way. One case breaks the obvious answer. On a site using PJAX the character does not need to refresh on every page, so the script has to sit outside the region PJAX swaps. Put it inside and the tag is evaluated again on each PJAX update.
Self-hosting adds a second ordering rule. You upload or clone the files, check in a browser that autoload.js and live2d.min.js open and are complete, then edit the live2d_path constant inside autoload.js to point at your dist directory. The trailing slash on that path is not optional, and until the constant resolves the character has a stylesheet and no model. Both files are worth opening by hand before you debug anything in the page, because a truncated upload looks identical to a configuration mistake.
Cubism SDK for Web has to be fetched into src before npm run build
To work on the widget itself you need Node.js and npm:
git clone https://github.com/stevenjoezhang/live2d-widget.git
npm installIf your models use Cubism 3 or newer, the SDK is not in the repository and cannot be added to it, because Live2D's licensing agreements forbid redistributing it. Download Cubism SDK for Web and extract it into src, the example given being src/CubismSdkForWeb-5-r.4. Cubism 2 models skip this step entirely.
npm run buildThat runs tsc and then rollup, moving TypeScript from src into build and from build into dist. package.json confirms the split: main points at build/index.js, types at build/index.d.ts, and the files array publishes build, dist, src and demo while excluding src/CubismSdkForWeb* and build/CubismSdkForWeb*. The SDK stays in your own checkout.
A fork on jsDelivr keeps serving the old tag until you push a new one
When you fork the repository and push your changes, the CDN form of the line changes:
<script src="https://fastly.jsdelivr.net/gh/username/live2d-widget@latest/autoload.js"></script>Replace username with your GitHub account. The @latest part is the trap: it follows GitHub tags, not your branch, so a commit that changes nothing about the tag leaves visitors on the previous file. You have to create a new git tag and push it to GitHub, and jsDelivr's own cache means the change takes further time still. Self-hosting removes both delays.
The version numbers show how upkeep runs here. package.json is at 1.0.1 and the default paths in the options table pin [email protected], while the most recent release on record is v0.9.0 from 2022-12-27. The last push to the default branch was on 2026-11-01. Code moves on master and the release tag does not follow it, so pin the version you tested rather than trusting @latest to mean your fork.
Editorial conclusion
live2d-widget suits a blog owner who wants a Live2D character on a page in one line and is prepared to point cdnPath at a model repository and edit waifu-tips.json by hand. It does not suit a commercial site, since the README limits the displayed models to research and study, or a workplace page, since it warns that the shipped tip text may not be suitable to read at work. Before you deploy, check three things: that your model host answers on the cdnPath you set, that every line in waifu-tips.json fits your audience, and that cubism2Path and cubism5Path resolve from your own domain if you self-host rather than loading jsDelivr.
Frequently asked questions
Is there a free alternative to Live2D for a live2d-widget setup?
The widget's own code is GPL-3.0, and the README notes that this code meets the Redistributable Code terms of the Live2D agreements. The runtime and the art are the parts you cannot simply take: Cubism SDK for Web may not be redistributed, and the models it displays may not be used commercially. For the same models outside a browser, the README lists desktop builds such as hime-display and PPet.
Can I use Live2D on iPad with live2d-widget?
Nothing in the README covers iPad or touch input. The documented integration is a script tag inside a page, and the only interactions it names are the drag option, which defaults to false, and the tool buttons. The project records testing in real browsers through BrowserStack without listing which devices those were.
How much does Live2D cost per month for live2d-widget users?
No subscription or price appears anywhere in the repository. What is documented is licensing: Cubism SDK 5 is provided under the Live2D Proprietary Software License, Cubism Components under the Live2D Open Software License, and SDK 2.1 under its own SDK license agreement. The widget code itself is under GNU General Public License v3.
Is Live2D Cubism the same as Live2D, in live2d-widget terms?
In this project the two are separate layers: Cubism Core is the runtime, and the widget wrapped around it is TypeScript under GPL-3.0. initWidget takes cubism2Path and cubism5Path as distinct options, and the README says the right core is selected from the version detected in the model, so one dist file serves both Cubism 2 and Cubism 3 or newer models.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/stevenjoezhang-live2d-widget)Star history chart for your README
[](https://hysenlabs.com/projects/stevenjoezhang-live2d-widget)Was this useful?