live2d-web documentation

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.

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 dev

Choose 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.

Vite JavaScript
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()
Next React
'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>
  )
}
Vue Vite
<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>
OBS overlay
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 })