
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
A Framework-agnostic Web Speech Recognition API wrapper.
_
/ \
/ \
/ \___
/ \_____
/ \___
/ \______
/ \__
/ \____
/=========================================>
Speere is a minimalist library that provides a simple interface to the Web Speech API's speech recognition capabilities. It offers a framework-agnostic approach that works seamlessly with vanilla JavaScript or any frontend framework (React, Vue, Svelte, etc.).
npm install speere
import { speech } from 'speere'
import { rule, grammarSet } from 'speere/grammar'
// Create grammar set with custom rules
const myGrammar = grammarSet([
{
name: 'commands',
alternatives: [
'start',
'stop',
'pause',
'resume',
'cancel',
'open',
'close',
],
},
{
name: 'colors',
alternatives: [
'red',
'green',
'blue',
'yellow',
'orange',
'purple',
'black',
'white',
],
},
])
// Initialize speech recognition
const recognition = speech({
grammar: myGrammar,
continuous: true,
onResult: (result, isFinal) => {
if (isFinal) {
console.log('Final result:', result[0].transcript)
}
},
})
// Start recognition
recognition.start()
// Later, stop recognition
recognition.stop()
// When you're done, clean up
recognition.dispose()
speech(options)The main function to initialize speech recognition.
Parameters:
options: Object - Configuration optionsOptions:
grammars: GrammarSet | SpeechGrammarList - Grammar rules for recognitioncontinuous: boolean - Whether to continuously recognize (default: false)interimResults: boolean - Whether to return interim results (default: false)lang: string - Language for recognition (default: browser's language)maxAlternatives: number - Maximum number of alternative recognitions (default: 1)onResult: (result: SpeechRecognitionResult, isFinal: boolean) => void - Callback for resultsonStart: () => void - Callback when recognition startsonEnd: () => void - Callback when recognition endsonError: (error: SpeechRecognitionError) => void - Callback for errorsReturns: An object with the following methods:
start(): Start speech recognitionstop(): Stop speech recognitionabort(): Abort speech recognition immediatelydispose(): Clean up resourcesSpeere provides a separate grammar module to make working with SpeechGrammarList easier.
import { rule, grammarSet } from 'speere/grammar'
rule(name, items, options)Creates a single grammar rule.
Parameters:
name: string - The name of the ruleitems: string[] | string - An array of possible values or a string with alternativesoptions: Object - Configuration options
isPublic: boolean - Whether the rule is public (default: true)weight: number - Weight for this grammar (0-1) (default: 1.0)Returns: A rule object that can be added to a grammar set
grammarSet(rules)Creates a collection of grammar rules.
Parameters:
rules: Rule[] - Array of rule objectsReturns: A grammar set object that can be passed to the speech function
import { speech } from 'speere'
import { rule, grammarSet } from 'speere/grammar'
const outputElement = document.getElementById('output')
const startButton = document.getElementById('start')
const stopButton = document.getElementById('stop')
// Define custom grammar
const actionRule = rule('actions', ['search', 'find', 'look up', 'browse'])
const myGrammar = grammarSet([actionRule])
const recognition = speech({
grammar: myGrammar,
continuous: true,
interimResults: true,
onResult: (result, isFinal) => {
if (isFinal) {
const transcript = result[0].transcript
outputElement.textContent += transcript + ' '
}
},
onStart: () => {
console.log('Recognition started')
},
onEnd: () => {
console.log('Recognition ended')
},
})
startButton.addEventListener('click', () => recognition.start())
stopButton.addEventListener('click', () => recognition.stop())
// Clean up on page unload
window.addEventListener('beforeunload', () => {
recognition.dispose()
})
import { useState, useEffect, useRef } from 'react'
import { speech } from 'speere'
import { rule, grammarSet } from 'speere/grammar'
function SpeechRecognizer() {
const [transcript, setTranscript] = useState('')
const [isListening, setIsListening] = useState(false)
const recognitionRef = useRef(null)
useEffect(() => {
if (!recognitionRef.current) {
// Create grammar for common voice commands
const voiceGrammar = grammarSet([
{ name: 'commands', alternatives: ['start', 'stop', 'clear'] },
])
recognitionRef.current = speech({
grammar: voiceGrammar,
continuous: true,
interimResults: true,
onResult: (result, isFinal) => {
if (isFinal) {
setTranscript((prev) => prev + result[0].transcript + ' ')
}
},
onStart: () => setIsListening(true),
onEnd: () => setIsListening(false),
})
}
return () => {
if (recognitionRef.current) {
recognitionRef.current.dispose()
}
}
}, [])
const toggleListening = () => {
if (isListening) {
recognitionRef.current.stop()
} else {
recognitionRef.current.start()
}
}
return (
<div>
<div className="transcript-box">
{transcript || (
<span className="placeholder">Speech will appear here...</span>
)}
</div>
<button onClick={toggleListening}>
{isListening ? 'Stop Listening' : 'Start Listening'}
</button>
</div>
)
}
# Clone the repository
git clone https://github.com/kou-by/speere.git
cd speere
# Install dependencies
npm install
# Run in development mode
npm run dev
# Run unit tests
npm run test
# Run tests in watch mode
npm run test:watch
# Generate coverage report
npm run coverage
# Run linting
npm run lint
# Run linting with auto-fix
npm run lint:fix
This project uses GitHub Actions for continuous integration. The following checks are automatically run:
When creating a PR, make sure all these checks pass.
Speere は、Web Speech API の音声認識機能へのシンプルなインターフェースを提供する軽量ライブラリです。フレームワークに依存しないアプローチを採用しており、vanilla JavaScript や任意のフロントエンドフレームワーク(React、Vue、Svelte など)とシームレスに連携します。
npm install speere
import { speech } from 'speere'
import { rule, grammarSet } from 'speere/grammar'
// カスタムルールで文法セットを作成
const myGrammar = grammarSet([
{
name: 'commands',
alternatives: [
'開始',
'停止',
'一時停止',
'再開',
'キャンセル',
'開く',
'閉じる',
],
},
{
name: 'colors',
alternatives: ['赤', '緑', '青', '黄', 'オレンジ', '紫', '黒', '白'],
},
])
// 音声認識を初期化
const recognition = speech({
grammar: myGrammar,
continuous: true,
onResult: (result, isFinal) => {
if (isFinal) {
console.log('最終結果:', result[0].transcript)
}
},
})
// 認識開始
recognition.start()
// 後で、認識停止
recognition.stop()
// 使い終わったらリソースを解放
recognition.dispose()
speech(options)音声認識を初期化するメイン関数。
パラメータ:
options: Object - 構成オプションオプション:
grammar: GrammarSet | SpeechGrammarList - 認識のための文法ルールcontinuous: boolean - 継続的に認識するかどうか(デフォルト: false)interimResults: boolean - 中間結果を返すかどうか(デフォルト: false)lang: string - 認識言語(デフォルト: ブラウザの言語)maxAlternatives: number - 代替認識の最大数(デフォルト: 1)onResult: (result: SpeechRecognitionResult, isFinal: boolean) => void - 結果のコールバックonStart: () => void - 認識開始時のコールバックonEnd: () => void - 認識終了時のコールバックonError: (error: SpeechRecognitionError) => void - エラー時のコールバック戻り値: 次のメソッドを持つオブジェクト:
start(): 音声認識を開始stop(): 音声認識を停止abort(): 音声認識を即座に中断dispose(): リソースをクリーンアップSpeere は SpeechGrammarList の扱いを簡単にするための別モジュールを提供しています。
import { rule, grammarSet } from 'speere/grammar'
rule(name, items, options)単一の文法ルールを作成します。
パラメータ:
name: string - ルールの名前items: string[] | string - 可能な値の配列または代替値を含む文字列options: Object - 構成オプション
isPublic: boolean - ルールを公開するかどうか(デフォルト: true)weight: number - この文法の重み(0-1)(デフォルト: 1.0)戻り値: 文法セットに追加できるルールオブジェクト
grammarSet(rules)文法ルールのコレクションを作成します。
パラメータ:
rules: Rule[] - ルールオブジェクトの配列戻り値: speech 関数に渡せる文法セットオブジェクト
import { speech } from 'speere'
import { rule, grammarSet } from 'speere/grammar'
const outputElement = document.getElementById('output')
const startButton = document.getElementById('start')
const stopButton = document.getElementById('stop')
// カスタム文法を定義
const actionRule = rule('actions', ['検索', '探す', '調べる', '閲覧'])
const myGrammar = grammarSet([actionRule])
const recognition = speech({
grammar: myGrammar,
continuous: true,
interimResults: true,
onResult: (result, isFinal) => {
if (isFinal) {
const transcript = result[0].transcript
outputElement.textContent += transcript + ' '
}
},
onStart: () => {
console.log('認識開始')
},
onEnd: () => {
console.log('認識終了')
},
})
startButton.addEventListener('click', () => recognition.start())
stopButton.addEventListener('click', () => recognition.stop())
// ページアンロード時にクリーンアップ
window.addEventListener('beforeunload', () => {
recognition.dispose()
})
import { useState, useEffect, useRef } from 'react'
import { speech } from 'speere'
import { rule, grammarSet } from 'speere/grammar'
function SpeechRecognizer() {
const [transcript, setTranscript] = useState('')
const [isListening, setIsListening] = useState(false)
const recognitionRef = useRef(null)
useEffect(() => {
if (!recognitionRef.current) {
// 音声コマンド用の文法を作成
const voiceGrammar = grammarSet([
{ name: 'commands', alternatives: ['開始', '停止', 'クリア'] },
])
recognitionRef.current = speech({
grammar: voiceGrammar,
continuous: true,
interimResults: true,
onResult: (result, isFinal) => {
if (isFinal) {
setTranscript((prev) => prev + result[0].transcript + ' ')
}
},
onStart: () => setIsListening(true),
onEnd: () => setIsListening(false),
})
}
return () => {
if (recognitionRef.current) {
recognitionRef.current.dispose()
}
}
}, [])
const toggleListening = () => {
if (isListening) {
recognitionRef.current.stop()
} else {
recognitionRef.current.start()
}
}
return (
<div>
<div className="transcript-box">
{transcript || (
<span className="placeholder">ここに音声が表示されます...</span>
)}
</div>
<button onClick={toggleListening}>
{isListening ? '認識停止' : '認識開始'}
</button>
</div>
)
}
# リポジトリをクローン
git clone https://github.com/kou-by/speere.git
cd speere
# 依存関係をインストール
npm install
# 開発モードで実行
npm run dev
# 単体テストを実行
npm run test
# テストをウォッチモードで実行
npm run test:watch
# カバレッジレポートを生成
npm run coverage
# リントを実行
npm run lint
# リントを実行して自動修正
npm run lint:fix
このプロジェクトは GitHub Actions を使用して継続的インテグレーションを実装しています。以下のチェックが自動的に実行されます:
PR を作成する際は、これらのチェックが全て通過することを確認してください。
FAQs
A Framework-agnostic Web Speech Recognition API wrapper.
We found that speere demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.