Agent skill

Jkvideo Bilibili React Native

by LeoYeAI in LeoYeAI/openclaw-master-skills

Expert skill for building and extending JKVideo, a React Native Bilibili-like client with DASH playback, danmaku, WBI signing, and live streaming

MITAuto-check passedMobile

Install Jkvideo Bilibili React Native

skills CLI
$ npx skills add LeoYeAI/openclaw-master-skills --skill jkvideo-bilibili-react-native -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install LeoYeAI/openclaw-master-skills jkvideo-bilibili-react-native --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/LeoYeAI/openclaw-master-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/jkvideo-bilibili-react-native .claude/skills/jkvideo-bilibili-react-native && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
jkvideo-bilibili-react-native
GitHub stars
2.2k
Token cost
~4.9k tokens
SKILL.md length
436 words
Files
2
Skills in repo
1,235
Repo updated
First seen
Licence
MIT

At a glance

Expert skill for building and extending JKVideo, a React Native Bilibili-like client with DASH playback, danmaku, WBI signing, and live streaming

  • Tasks that involve Cross-platform mobile apps
  • SKILL.md covers Installation & Setup, Project Structure, Key Technology Stack and WBI Signature Implementation, plus 13 more sections
  • Calls npx, npm and node; reaches bilibili.com and github.com

What it does

Jkvideo Bilibili React Native is an agent skill from LeoYeAI/openclaw-master-skills. Expert skill for building and extending JKVideo, a React Native Bilibili-like client with DASH playback, danmaku, WBI signing, and live streaming

Its SKILL.md is about 4.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 1 other file (for example `_meta.json`).

It sits in Mobile, covering Cross-platform mobile apps. It works with Bilibili, React Native, Expo and Android. The repository describes itself as: 🧠 Curated collection of 1209+ best OpenClaw skills — weekly updated by MyClaw.ai. The licence is MIT.

When your agent uses it

  • Tasks that involve Cross-platform mobile apps

Example prompts

  • “/jkvideo-bilibili-react-native”

Requirements

  • Node.js

What it can do on your machine

Read from SKILL.md and the folder at commit e5199b5. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npx
    • npm
    • node
    • git

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • bilibili.com
    • github.com
    • api.bilibili.com
    • api.live.bilibili.com

    Also links to:

    • ara.so

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Jkvideo Bilibili React Native loads about 4.9k tokens when it runs. Until then it costs about 44 tokens; SKILL.md has 436 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~44
When it runs · the whole SKILL.md, loaded when a task matches
~4.9k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from LeoYeAI/openclaw-master-skills at commit e5199b5, republished under its MIT licence (© LeoYeAI). 436 words, ~4,940 tokens.

Download SKILL.mdSave it as .claude/skills/jkvideo-bilibili-react-native/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
jkvideo-bilibili-react-native
description
Expert skill for building and extending JKVideo, a React Native Bilibili-like client with DASH playback, danmaku, WBI signing, and live streaming
triggers
build a bilibili react native app, add DASH video playback to expo, implement danmaku bullet comments, WBI signature bilibili API, react native live streaming…

JKVideo Bilibili React Native Client

Skill by ara.so — Daily 2026 Skills collection.

JKVideo is a full-featured third-party Bilibili client built with React Native 0.83 + Expo SDK 55. It supports DASH adaptive streaming, real-time danmaku (bullet comments), WBI API signing, QR code login, live streaming with WebSocket danmaku, and a download manager with LAN QR sharing.


Installation & Setup

Prerequisites
  • Node.js 18+
  • npm or yarn
  • For Android: Android Studio + SDK
  • For iOS: macOS + Xcode 15+
Quick Start (Expo Go — no compilation)
bash
git clone https://github.com/tiajinsha/JKVideo.git
cd JKVideo
npm install
npx expo start

Scan the QR with Expo Go app. Note: DASH 1080P+ requires Dev Build.

bash
npm install
npx expo run:android   # Android
npx expo run:ios       # iOS (macOS + Xcode required)
Web with Image Proxy
bash
npm install
npx expo start --web
# In a separate terminal:
node scripts/proxy.js   # Starts proxy on port 3001 to bypass Bilibili referer restrictions
Install APK Directly (Android)

Download from Releases — enable "Install from unknown sources" in Android settings.


Project Structure

app/
  index.tsx            # Home (PagerView hot/live tabs)
  video/[bvid].tsx     # Video detail (playback + comments + danmaku)
  live/[roomId].tsx    # Live detail (HLS + real-time danmaku)
  search.tsx           # Search page
  downloads.tsx        # Download manager
  settings.tsx         # Settings (quality, logout)

components/            # UI: player, danmaku overlay, cards
hooks/                 # Data hooks: video list, streams, danmaku
services/              # Bilibili API (axios + cookie interceptor)
store/                 # Zustand stores: auth, download, video, settings
utils/                 # Helpers: format, image proxy, MPD builder

Key Technology Stack

LayerTechnology
FrameworkReact Native 0.83 + Expo SDK 55
Routingexpo-router v4 (file-system, Stack nav)
StateZustand
HTTPAxios
Storage@react-native-async-storage/async-storage
Videoreact-native-video (DASH MPD / HLS / MP4)
Fallbackreact-native-webview (HTML5 video injection)
Pagingreact-native-pager-view
Icons@expo/vector-icons (Ionicons)

WBI Signature Implementation

Bilibili requires WBI signing for most API calls. JKVideo implements pure TypeScript MD5 with 12h nav cache.

typescript
// utils/wbi.ts — pure TS MD5, no external crypto deps
const MIXIN_KEY_ENC_TAB = [
  46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35,
  27, 43, 5, 49, 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13
];

function getMixinKey(rawKey: string): string {
  return MIXIN_KEY_ENC_TAB
    .map(i => rawKey[i])
    .join('')
    .slice(0, 32);
}

export async function signWbi(
  params: Record<string, string | number>,
  imgKey: string,
  subKey: string
): Promise<Record<string, string | number>> {
  const mixinKey = getMixinKey(imgKey + subKey);
  const wts = Math.floor(Date.now() / 1000);
  const signParams = { ...params, wts };

  // Sort params alphabetically, filter special chars
  const query = Object.keys(signParams)
    .sort()
    .map(k => {
      const val = String(signParams[k]).replace(/[!'()*]/g, '');
      return `${encodeURIComponent(k)}=${encodeURIComponent(val)}`;
    })
    .join('&');

  const wRid = md5(query + mixinKey); // pure TS md5
  return { ...signParams, w_rid: wRid };
}

// Fetch and cache nav keys (12h TTL)
export async function getWbiKeys(): Promise<{ imgKey: string; subKey: string }> {
  const cached = await AsyncStorage.getItem('wbi_keys');
  if (cached) {
    const { keys, ts } = JSON.parse(cached);
    if (Date.now() - ts < 12 * 3600 * 1000) return keys;
  }
  const res = await api.get('/x/web-interface/nav');
  const { img_url, sub_url } = res.data.data.wbi_img;
  const imgKey = img_url.split('/').pop()!.replace('.png', '');
  const subKey = sub_url.split('/').pop()!.replace('.png', '');
  const keys = { imgKey, subKey };
  await AsyncStorage.setItem('wbi_keys', JSON.stringify({ keys, ts: Date.now() }));
  return keys;
}

Bilibili API Service

typescript
// services/api.ts
import axios from 'axios';
import AsyncStorage from '@react-native-async-storage/async-storage';

export const api = axios.create({
  baseURL: 'https://api.bilibili.com',
  timeout: 15000,
  headers: {
    'User-Agent': 'Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36',
    'Referer': 'https://www.bilibili.com',
  },
});

// Inject SESSDATA cookie from store
api.interceptors.request.use(async (config) => {
  const sessdata = await AsyncStorage.getItem('SESSDATA');
  if (sessdata) {
    config.headers['Cookie'] = `SESSDATA=${sessdata}`;
  }
  return config;
});

// Popular video list (WBI signed)
export async function getPopularVideos(pn = 1, ps = 20) {
  const { imgKey, subKey } = await getWbiKeys();
  const signed = await signWbi({ pn, ps }, imgKey, subKey);
  const res = await api.get('/x/web-interface/popular', { params: signed });
  return res.data.data.list;
}

// Video stream info (DASH)
export async function getVideoStream(bvid: string, cid: number, qn = 80) {
  const { imgKey, subKey } = await getWbiKeys();
  const signed = await signWbi(
    { bvid, cid, qn, fnval: 4048, fnver: 0, fourk: 1 },
    imgKey, subKey
  );
  const res = await api.get('/x/player/wbi/playurl', { params: signed });
  return res.data.data;
}

// Live stream URL
export async function getLiveStreamUrl(roomId: number) {
  const res = await api.get('/room/v1/Room/playUrl', {
    params: { cid: roomId, quality: 4, platform: 'h5' },
    baseURL: 'https://api.live.bilibili.com',
  });
  return res.data.data.durl[0].url; // HLS m3u8
}

DASH MPD Builder

ExoPlayer needs a local MPD file. JKVideo generates it from Bilibili's DASH response:

typescript
// utils/buildDashMpd.ts
export function buildDashMpdUri(dashData: BiliDashData): string {
  const { duration, video, audio } = dashData;

  const videoAdaptations = video.map((v) => `
    <AdaptationSet mimeType="video/mp4" segmentAlignment="true">
      <Representation id="${v.id}" bandwidth="${v.bandwidth}"
        codecs="${v.codecs}" width="${v.width}" height="${v.height}">
        <BaseURL>${escapeXml(v.baseUrl)}</BaseURL>
        <SegmentBase indexRange="${v.segmentBase.indexRange}">
          <Initialization range="${v.segmentBase.initialization}"/>
        </SegmentBase>
      </Representation>
    </AdaptationSet>`).join('');

  const audioAdaptations = audio.map((a) => `
    <AdaptationSet mimeType="audio/mp4" segmentAlignment="true">
      <Representation id="${a.id}" bandwidth="${a.bandwidth}" codecs="${a.codecs}">
        <BaseURL>${escapeXml(a.baseUrl)}</BaseURL>
        <SegmentBase indexRange="${a.segmentBase.indexRange}">
          <Initialization range="${a.segmentBase.initialization}"/>
        </SegmentBase>
      </Representation>
    </AdaptationSet>`).join('');

  const mpd = `<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" type="static"
  mediaPresentationDuration="PT${duration}S" minBufferTime="PT1.5S">
  <Period duration="PT${duration}S">
    ${videoAdaptations}
    ${audioAdaptations}
  </Period>
</MPD>`;

  // Write to temp file, return file:// URI for ExoPlayer
  const path = `${FileSystem.cacheDirectory}dash_${Date.now()}.mpd`;
  FileSystem.writeAsStringAsync(path, mpd);
  return path;
}

Video Player Component

typescript
// components/VideoPlayer.tsx
import Video from 'react-native-video';
import { WebView } from 'react-native-webview';
import { useVideoStore } from '../store/videoStore';

interface VideoPlayerProps {
  bvid: string;
  cid: number;
  autoPlay?: boolean;
}

export function VideoPlayer({ bvid, cid, autoPlay = false }: VideoPlayerProps) {
  const [mpdUri, setMpdUri] = useState<string | null>(null);
  const [useFallback, setUseFallback] = useState(false);
  const { setCurrentVideo } = useVideoStore();

  useEffect(() => {
    loadStream();
  }, [bvid, cid]);

  async function loadStream() {
    try {
      const stream = await getVideoStream(bvid, cid);
      if (stream.dash) {
        const uri = await buildDashMpdUri(stream.dash);
        setMpdUri(uri);
      } else {
        setUseFallback(true);
      }
    } catch {
      setUseFallback(true);
    }
  }

  if (useFallback) {
    // WebView fallback for Expo Go / Web
    return (
      <WebView
        source={{ uri: `https://www.bilibili.com/video/${bvid}` }}
        allowsInlineMediaPlayback
        mediaPlaybackRequiresUserAction={false}
      />
    );
  }

  return (
    <Video
      source={{ uri: mpdUri! }}
      style={{ width: '100%', aspectRatio: 16 / 9 }}
      controls
      paused={!autoPlay}
      resizeMode="contain"
      onLoad={() => setCurrentVideo({ bvid, cid })}
    />
  );
}

Danmaku System

Video Danmaku (XML timeline sync)
typescript
// hooks/useDanmaku.ts
export function useDanmaku(cid: number) {
  const [danmakuList, setDanmakuList] = useState<Danmaku[]>([]);

  useEffect(() => {
    fetchDanmaku(cid);
  }, [cid]);

  async function fetchDanmaku(cid: number) {
    const res = await api.get(`/x/v1/dm/list.so?oid=${cid}`, {
      responseType: 'arraybuffer',
    });
    // Parse XML danmaku
    const xml = new TextDecoder('utf-8').decode(res.data);
    const items = parseXmlDanmaku(xml); // parse <d p="time,...">text</d>
    setDanmakuList(items);
  }

  return danmakuList;
}

// components/DanmakuOverlay.tsx — 5-lane floating display
const LANE_COUNT = 5;

export function DanmakuOverlay({ danmakuList, currentTime }: Props) {
  const activeDanmaku = danmakuList.filter(
    d => d.time >= currentTime - 0.1 && d.time < currentTime + 0.1
  );

  return (
    <View style={StyleSheet.absoluteFillObject} pointerEvents="none">
      {activeDanmaku.map((d, i) => (
        <DanmakuItem
          key={d.id}
          text={d.text}
          color={d.color}
          lane={i % LANE_COUNT}
        />
      ))}
    </View>
  );
}
Live Danmaku (WebSocket)
typescript
// hooks/useLiveDanmaku.ts
const LIVE_WS = 'wss://broadcastlv.chat.bilibili.com/sub';

export function useLiveDanmaku(roomId: number) {
  const [messages, setMessages] = useState<LiveMessage[]>([]);
  const wsRef = useRef<WebSocket | null>(null);

  useEffect(() => {
    const ws = new WebSocket(LIVE_WS);
    wsRef.current = ws;

    ws.onopen = () => {
      // Send join room packet
      const body = JSON.stringify({ roomid: roomId, uid: 0, protover: 2 });
      ws.send(buildPacket(body, 7)); // op=7: enter room
      startHeartbeat(ws);
    };

    ws.onmessage = async (event) => {
      const packets = await decompressPacket(event.data);
      packets.forEach(packet => {
        if (packet.op === 5) {
          const msg = JSON.parse(packet.body);
          handleCommand(msg);
        }
      });
    };

    return () => ws.close();
  }, [roomId]);

  function handleCommand(msg: any) {
    switch (msg.cmd) {
      case 'DANMU_MSG':
        setMessages(prev => [{
          type: 'danmaku',
          text: msg.info[1],
          user: msg.info[2][1],
          isGuard: msg.info[7] > 0, // 舰长标记
        }, ...prev].slice(0, 200));
        break;
      case 'SEND_GIFT':
        setMessages(prev => [{
          type: 'gift',
          user: msg.data.uname,
          gift: msg.data.giftName,
          count: msg.data.num,
        }, ...prev].slice(0, 200));
        break;
    }
  }

  return messages;
}

Zustand State Stores

typescript
// store/videoStore.ts
import { create } from 'zustand';

interface VideoState {
  currentVideo: { bvid: string; cid: number } | null;
  isMiniplayer: boolean;
  quality: number; // 80=1080P, 112=1080P+, 120=4K
  setCurrentVideo: (video: { bvid: string; cid: number }) => void;
  setMiniplayer: (val: boolean) => void;
  setQuality: (q: number) => void;
}

export const useVideoStore = create<VideoState>((set) => ({
  currentVideo: null,
  isMiniplayer: false,
  quality: 80,
  setCurrentVideo: (video) => set({ currentVideo: video }),
  setMiniplayer: (val) => set({ isMiniplayer: val }),
  setQuality: (q) => set({ quality: q }),
}));

// store/authStore.ts
interface AuthState {
  sessdata: string | null;
  isLoggedIn: boolean;
  login: (sessdata: string) => Promise<void>;
  logout: () => Promise<void>;
}

export const useAuthStore = create<AuthState>((set) => ({
  sessdata: null,
  isLoggedIn: false,
  login: async (sessdata) => {
    await AsyncStorage.setItem('SESSDATA', sessdata);
    set({ sessdata, isLoggedIn: true });
  },
  logout: async () => {
    await AsyncStorage.removeItem('SESSDATA');
    set({ sessdata: null, isLoggedIn: false });
  },
}));

QR Code Login

typescript
// hooks/useQrLogin.ts
export function useQrLogin() {
  const { login } = useAuthStore();
  const [qrUrl, setQrUrl] = useState('');
  const [qrKey, setQrKey] = useState('');
  const pollRef = useRef<ReturnType<typeof setInterval>>();

  async function generateQr() {
    const res = await api.get('/x/passport-login/web/qrcode/generate');
    const { url, qrcode_key } = res.data.data;
    setQrUrl(url);
    setQrKey(qrcode_key);
    startPolling(qrcode_key);
  }

  function startPolling(key: string) {
    pollRef.current = setInterval(async () => {
      const res = await api.get('/x/passport-login/web/qrcode/poll', {
        params: { qrcode_key: key },
      });
      const { code } = res.data.data;
      if (code === 0) {
        // Extract SESSDATA from Set-Cookie header
        const setCookie = res.headers['set-cookie'] ?? [];
        const sessdataCookie = setCookie
          .find((c: string) => c.includes('SESSDATA='));
        const sessdata = sessdataCookie?.match(/SESSDATA=([^;]+)/)?.[1];
        if (sessdata) {
          await login(sessdata);
          clearInterval(pollRef.current);
        }
      }
    }, 2000);
  }

  useEffect(() => () => clearInterval(pollRef.current), []);
  return { qrUrl, generateQr };
}

Download Manager + LAN Sharing

typescript
// store/downloadStore.ts
import * as FileSystem from 'expo-file-system';

export const useDownloadStore = create((set, get) => ({
  downloads: [] as Download[],

  startDownload: async (bvid: string, quality: number) => {
    const stream = await getVideoStream(bvid, /* cid */ 0, quality);
    const url = stream.durl?.[0]?.url ?? stream.dash?.video?.[0]?.baseUrl;
    const path = `${FileSystem.documentDirectory}downloads/${bvid}_${quality}.mp4`;

    const task = FileSystem.createDownloadResumable(url, path, {
      headers: { Referer: 'https://www.bilibili.com' },
    }, (progress) => {
      // Update progress in store
      set(state => ({
        downloads: state.downloads.map(d =>
          d.bvid === bvid ? { ...d, progress: progress.totalBytesWritten / progress.totalBytesExpectedToWrite } : d
        ),
      }));
    });

    set(state => ({
      downloads: [...state.downloads, { bvid, quality, path, progress: 0, task }],
    }));
    await task.downloadAsync();
  },
}));

// LAN HTTP server for QR sharing (scripts/proxy.js pattern)
// Built-in HTTP server serves downloaded file, generates QR with local IP
import { createServer } from 'http';
import { networkInterfaces } from 'os';

function getLanIp(): string {
  const nets = networkInterfaces();
  for (const name of Object.keys(nets)) {
    for (const net of nets[name]!) {
      if (net.family === 'IPv4' && !net.internal) return net.address;
    }
  }
  return 'localhost';
}

expo-router Navigation Patterns

typescript
// app/video/[bvid].tsx
import { useLocalSearchParams } from 'expo-router';

export default function VideoDetail() {
  const { bvid } = useLocalSearchParams<{ bvid: string }>();
  // ...
}

// Navigate to video
import { router } from 'expo-router';
router.push(`/video/${bvid}`);

// Navigate to live room
router.push(`/live/${roomId}`);

// Navigate back
router.back();

Image Proxy (Web)

Bilibili images block direct loading in browsers via Referer header. Use the bundled proxy:

javascript
// scripts/proxy.js (port 3001)
// Usage in components:
function proxyImage(url: string): string {
  if (Platform.OS === 'web') {
    return `http://localhost:3001/proxy?url=${encodeURIComponent(url)}`;
  }
  return url; // Native handles Referer correctly
}

Quality Level Reference

CodeQuality
16360P
32480P
64720P
801080P
1121080P+ (大会员)
1161080P60 (大会员)
1204K (大会员)

Show full SKILL.md (174 more words)Show less

Common Patterns

Add a New API Endpoint
typescript
// services/api.ts
export async function getVideoInfo(bvid: string) {
  const { imgKey, subKey } = await getWbiKeys();
  const signed = await signWbi({ bvid }, imgKey, subKey);
  const res = await api.get('/x/web-interface/view', { params: signed });
  return res.data.data;
}
Add a New Screen
typescript
// app/history.tsx — automatically becomes /history route
import { Stack } from 'expo-router';

export default function HistoryScreen() {
  return (
    <>
      <Stack.Screen options={{ title: '历史记录' }} />
      {/* screen content */}
    </>
  );
}
Create a Zustand Slice
typescript
// store/settingsStore.ts
import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import AsyncStorage from '@react-native-async-storage/async-storage';

export const useSettingsStore = create(
  persist(
    (set) => ({
      defaultQuality: 80,
      danmakuEnabled: true,
      setDefaultQuality: (q: number) => set({ defaultQuality: q }),
      toggleDanmaku: () => set(s => ({ danmakuEnabled: !s.danmakuEnabled })),
    }),
    {
      name: 'jkvideo-settings',
      storage: createJSONStorage(() => AsyncStorage),
    }
  )
);

Troubleshooting

IssueSolution
DASH not playing in Expo GoUse Dev Build: npx expo run:android
Images not loading on WebRun node scripts/proxy.js and ensure web uses proxy URLs
API returns 412 / risk controlEnsure WBI signature is fresh; clear cached keys via AsyncStorage
4K/1080P+ not availableLogin with a Bilibili Premium (大会员) account
Live stream failsApp auto-selects HLS; FLV is not supported by ExoPlayer/HTML5
QR code expiredClose and reopen the login modal to regenerate
Cookie not persistingCheck AsyncStorage permissions; SESSDATA key must match interceptor
WebSocket danmaku dropsIncrease heartbeat frequency; check packet decompression (zlib)
Build fails on iOSRun cd ios && pod install then rebuild

Known Limitations

  • Dynamic feed / posting / likes require bili_jct CSRF token — not yet implemented
  • FLV live streams are not supported; app auto-selects HLS fallback
  • Web platform requires local proxy server for images (Referer restriction)
  • 4K / 1080P+ requires logged-in Bilibili Premium account
  • QR code expires after 10 minutes — reopen modal to refresh

© LeoYeAI, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file in skills/jkvideo-bilibili-react-native of LeoYeAI/openclaw-master-skills.

  • SKILL.md
  • _meta.json

Open the folder on GitHubat commit e5199b5

Compare with similar skills

Jkvideo Bilibili React Native next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Jkvideo Bilibili React Native compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Jkvideo Bilibili React Native this skillLeoYeAI/openclaw-master-skills2.2k—~4.9kAutomated safety check: PassMIT
Expo Tailwind SetupCherryHQ/cherry-studio-app4k8 repos~3kAutomated safety check: PassMIT
Screenmapaleqsio/screenmap244—~7.2kAutomated safety check: PassMIT
Expo Brownfield Integrationmweinbach/agent-coworker1562 repos~900Automated safety check: NotesCustom licence
Expo UIarcboxlabs/linkcode155—~1.2kAutomated safety check: PassMIT
Simfleetentropyconquers/simfleet118—~1.5kAutomated safety check: PassMIT

Similar skills

  • Expo Tailwind Setup

    CherryHQ/cherry-studio-app

    Set up Tailwind CSS v4 in Expo with react-native-css and NativeWind v5 for universal styling

    4k GitHub starsUsed in 8 repos~3k tokens
    MobileAuto-check passed
  • Screenmap

    aleqsio/screenmap

    Generate a visual navigation map of an Expo / React Native or NativeScript app.

    244 GitHub stars~7.2k tokensUpdated 6 days ago
    MobileAuto-check passed
  • Expo Brownfield Integration

    mweinbach/agent-coworker

    Helps add Expo and React Native to an existing native iOS or Android app, and choose between a prebuilt AAR or XCFramework and a fully integrated build.

    156 GitHub starsUsed in 2 repos~900 tokens
    MobileAuto-check: notes
  • Expo UI

    arcboxlabs/linkcode

    Framework (OSS). An agent skill from arcboxlabs/linkcode.

    155 GitHub stars~1.2k tokensUpdated 12 days ago
    MobileAuto-check passed
  • Simfleet

    entropyconquers/simfleet

    Operate a simfleet device fleet: slimmed iOS simulators and Android emulators, parallel React Native worktree lanes with leased Metro ports, the native build cache, and per-agent device claims.

    118 GitHub stars~1.5k tokensUpdated 12 days ago
    MobileAuto-check passed
  • Code Review React Native

    talsec/Free-RASP-ReactNative

    Performs strict code reviews on React Native plugin projects covering TypeScript, the Kotlin (Android) and Swift (iOS) native bridges, and the Expo config plugin.

    176 GitHub stars~3.7k tokensUpdated 5 days ago
    MobileAuto-check passed

More from LeoYeAI/openclaw-master-skills

All 1,235 skills in this repo
  • DevOps Pipeline Management

    LeoYeAI/openclaw-master-skills

    Manages pipelines on a DevOps quality and efficiency platform through its OpenAPI: list workspaces and templates, create, update, run and cancel pipelines, and read run records.

    2.2k GitHub stars~4.2k tokensUpdated 2 mo ago
    Auto-check: notes
  • Feishu Document Collaboration

    LeoYeAI/openclaw-master-skills

    Patches OpenClaw's Feishu extension so an edited document triggers an isolated agent session that reads the doc and replies inline, turning it into a live chat space.

    2.2k GitHub stars~2k tokensUpdated 2 mo ago
    Auto-check passed
  • Files Memory System

    LeoYeAI/openclaw-master-skills

    Multi-context memory management system for OpenClaw agents with group-isolated storage, global shared memory, workspace organization, and group-specific skills isolation.

    2.2k GitHub stars~3.8k tokensUpdated 2 mo ago
    Auto-check passed
  • GEO-Claw AI Visibility Agent

    LeoYeAI/openclaw-master-skills

    Runs a brand's AI-search visibility work end to end: diagnosing how AI platforms represent it, repositioning it, producing AI-optimized content and monitoring ongoing mentions.

    2.2k GitHub stars~4.7k tokensUpdated 2 mo ago
    Auto-check passed
  • Google Workspace CLI

    LeoYeAI/openclaw-master-skills

    Installs and authenticates the gws CLI, then automates Gmail, Drive, Sheets, Calendar, Docs, Chat and Tasks with ready-made recipes, persona bundles and security audits.

    2.2k GitHub stars~2.6k tokensUpdated 2 mo ago
    Auto-check: notes
  • HealthFit Health Advisors

    LeoYeAI/openclaw-master-skills

    Runs four advisor roles, a fitness coach, nutritionist, data analyst and TCM practitioner, to build a health profile and track workouts, diet and wellness over time.

    2.2k GitHub stars~4.4k tokensUpdated 2 mo ago
    Auto-check passed

Categories

Questions about Jkvideo Bilibili React Native

What does Jkvideo Bilibili React Native do?

Expert skill for building and extending JKVideo, a React Native Bilibili-like client with DASH playback, danmaku, WBI signing, and live streaming. Jkvideo Bilibili React Native is an agent skill from LeoYeAI/openclaw-master-skills.

When should I use Jkvideo Bilibili React Native?

Jkvideo Bilibili React Native fits situations like: tasks that involve Cross-platform mobile apps.

How do I install Jkvideo Bilibili React Native in Claude Code?

Run `npx skills add LeoYeAI/openclaw-master-skills --skill jkvideo-bilibili-react-native -a claude-code`. Or copy the skill folder (skills/jkvideo-bilibili-react-native in LeoYeAI/openclaw-master-skills) into .claude/skills/jkvideo-bilibili-react-native in your project. Claude Code loads it when a task matches its description.

How do I install Jkvideo Bilibili React Native in Codex?

Run `npx skills add LeoYeAI/openclaw-master-skills --skill jkvideo-bilibili-react-native -a codex`. Or copy the skill folder (skills/jkvideo-bilibili-react-native in LeoYeAI/openclaw-master-skills) into .agents/skills/jkvideo-bilibili-react-native in your project. Codex loads it when a task matches its description.

Can I use Jkvideo Bilibili React Native in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add LeoYeAI/openclaw-master-skills --skill jkvideo-bilibili-react-native -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/jkvideo-bilibili-react-native, .gemini/skills/jkvideo-bilibili-react-native, .github/skills/jkvideo-bilibili-react-native and .opencode/skills/jkvideo-bilibili-react-native in your project.

What does Jkvideo Bilibili React Native need to run?

Going by SKILL.md and its folder, Jkvideo Bilibili React Native needs the command-line tools its instructions call (npx, npm, node and git). Our summary lists: Node.js.

Does Jkvideo Bilibili React Native access the network?

SKILL.md names 5 domains. In commands or code: bilibili.com, github.com, api.bilibili.com and api.live.bilibili.com; the agent is likely to contact these when it follows the instructions. As links in the text: ara.so. This is read from the text; nothing was executed.

Is Jkvideo Bilibili React Native safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Jkvideo Bilibili React Native use?

Jkvideo Bilibili React Native is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Jkvideo Bilibili React Native use?

About 4.9k tokens (SKILL.md is roughly 20k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Jkvideo Bilibili React Native?

Skills that share tags, products or a category with Jkvideo Bilibili React Native: Expo Tailwind Setup (CherryHQ/cherry-studio-app, 4k stars), Screenmap (aleqsio/screenmap, 244 stars), Expo Brownfield Integration (mweinbach/agent-coworker, 156 stars) and Expo UI (arcboxlabs/linkcode, 155 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Jkvideo Bilibili React Native?

LeoYeAI (a GitHub user) maintains it in LeoYeAI/openclaw-master-skills, which has 2,161 GitHub stars. The repository holds 1,235 skills in this directory. The repository was last updated on July 20, 2026.

Source: LeoYeAI/openclaw-master-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.