Examples
Start from four verified framework and overlay examples.
Buildable projects
The repository includes Vite JavaScript, Next React, Vue Vite and transparent OBS overlay examples. CI typechecks and production-builds all four. Each expects Core at /live2dcubismcore.min.js and a model at /models/model.model3.json.
- Complete Vite JavaScript source
- Complete Next React source
- Complete Vue Vite source
- Complete OBS overlay source
pnpm install
pnpm --filter @live2d-web/example-vanilla-vite dev
pnpm --filter @live2d-web/example-next-react dev
pnpm --filter @live2d-web/example-vue-vite dev
pnpm --filter @live2d-web/example-obs-overlay devChoose the closest starting point
Use Vite JavaScript for the smallest imperative lifecycle, Next React for a Client Component boundary, Vue Vite for framework lifecycle integration, and OBS overlay for a transparent browser source controlled by query parameters. None of the examples bundles Cubism Core or a model.
Provide local assets
Copy licensed Core to /live2dcubismcore.min.js and an exported model directory under /models. Preserve every relative reference from model3. The examples deliberately fail with a useful asset error instead of downloading proprietary files from a default CDN.
Build before adapting
Run the example unchanged, verify model load and cleanup, then replace the model URL and framing. A production build is the final check for SSR boundaries, worker URLs and asset base paths.
import { createLive2D } from 'live2d-web'
const character = await createLive2D({
container: document.querySelector('#avatar'),
coreUrl: '/live2dcubismcore.min.js',
src: '/models/model.model3.json',
})
await character.motion('TapBody', 0)
// When the host view is removed:
character.dispose()'use client'
import { Live2DCanvas, Live2DModel } from 'live2d-web/react'
export function Avatar() {
return (
<Live2DCanvas coreUrl="/live2dcubismcore.min.js">
<Live2DModel src="/models/model.model3.json" />
</Live2DCanvas>
)
}<script setup lang="ts">
import { createLive2D } from 'live2d-web'
import { onBeforeUnmount, onMounted, ref } from 'vue'
const host = ref<HTMLElement>()
let character: Awaited<ReturnType<typeof createLive2D>> | undefined
onMounted(async () => {
character = await createLive2D({
container: host.value!,
coreUrl: '/live2dcubismcore.min.js',
src: '/models/model.model3.json',
})
})
onBeforeUnmount(() => character?.dispose())
</script>
<template><div ref="host" class="avatar" /></template>import { createLive2D } from 'live2d-web'
const query = new URLSearchParams(location.search)
const character = await createLive2D({
container: document.querySelector('#overlay')!,
coreUrl: '/live2dcubismcore.min.js',
fit: query.get('fit') === 'full' ? 'full' : 'upper-body',
src: query.get('model') ?? '/models/model.model3.json',
})
addEventListener('pagehide', () => character.dispose(), { once: true })