or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-sentiment

AFINN-based sentiment analysis for Node.js with multi-language support and custom scoring strategies

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/sentiment@5.0.x

To install, run

npx @tessl/cli install tessl/npm-sentiment@5.0.0

index.mddocs/

Sentiment

Sentiment is a high-performance AFINN-based sentiment analysis library for Node.js that uses the AFINN-165 wordlist and Emoji Sentiment Ranking to analyze the emotional tone of text input. It provides comprehensive sentiment scoring with detailed breakdowns, supports multiple languages through a plugin system, and offers custom scoring strategies for handling negation and emphasis.

Package Information

  • Package Name: sentiment
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install sentiment

Core Imports

const Sentiment = require('sentiment');

ES6 import (if using a transpiler):

import Sentiment from 'sentiment';

Basic Usage

const Sentiment = require('sentiment');
const sentiment = new Sentiment();

// Analyze sentiment of text
const result = sentiment.analyze('Cats are totally amazing!');
console.log(result);
// {
//   score: 4,
//   comparative: 1,
//   calculation: [{ amazing: 4 }],
//   tokens: ['cats', 'are', 'totally', 'amazing'],
//   words: ['amazing'],
//   positive: ['amazing'],
//   negative: []
// }

// Override AFINN wordlist
const customResult = sentiment.analyze('Cats are stupid.', {
  extras: { 'cats': 5, 'stupid': -1 }
});
console.log(customResult.score); // 4 (5 + -1)

Architecture

Sentiment analysis is built around several key components:

  • AFINN Wordlist: Pre-scored word database with values from -5 (negative) to +5 (positive)
  • Emoji Support: Sentiment rankings for emojis integrated into all languages
  • Tokenization: Text preprocessing that splits input into individual words and emojis
  • Language System: Pluggable language support with custom scoring strategies
  • Scoring Strategy: Per-language logic for handling negation, emphasis, and context

Capabilities

Sentiment Analysis

Analyzes the emotional tone of input text and returns detailed sentiment metrics.

/**
 * Performs sentiment analysis on the provided input phrase
 * @param {string} phrase - Input phrase to analyze
 * @param {object} [opts] - Analysis options
 * @param {string} [opts.language='en'] - Language code for analysis (defaults to 'en')
 * @param {object} [opts.extras={}] - Additional word/score pairs to add or overwrite
 * @param {function} [callback] - Optional callback function
 * @returns {object} Sentiment analysis result
 */
analyze(phrase, opts, callback);

Usage Examples:

const sentiment = new Sentiment();

// Basic analysis
const result = sentiment.analyze('I love sunny days!');

// With language specification
const frenchResult = sentiment.analyze('Je suis heureux', { 
  language: 'fr' 
});

// With custom word overrides
const customResult = sentiment.analyze('This product is okay', {
  extras: { 'okay': 2 }
});

// With callback (async)
sentiment.analyze('Hello world', (err, result) => {
  console.log(result.score);
});

Language Registration

Registers support for additional languages with custom word lists and scoring strategies.

/**
 * Registers a new language for sentiment analysis
 * @param {string} languageCode - Two-digit language code (e.g., 'fr', 'es')
 * @param {object} language - Language configuration object
 * @param {object} language.labels - Word-to-score mapping for the language
 * @param {object} [language.scoringStrategy] - Custom scoring strategy for the language
 */
registerLanguage(languageCode, language);

Usage Examples:

const sentiment = new Sentiment();

// Register French language
sentiment.registerLanguage('fr', {
  labels: {
    'bon': 3,
    'mauvais': -3,
    'excellent': 5,
    'horrible': -5
  }
});

// Register with custom scoring strategy
sentiment.registerLanguage('es', {
  labels: {
    'bueno': 3,
    'malo': -3
  },
  scoringStrategy: {
    apply: function(tokens, cursor, tokenScore) {
      // Custom negation handling for Spanish
      if (cursor > 0 && tokens[cursor - 1] === 'no') {
        return -tokenScore;
      }
      return tokenScore;
    }
  }
});

// Use registered language
const result = sentiment.analyze('Très bon!', { language: 'fr' });

Types

Sentiment Constructor

/**
 * Creates a new Sentiment analyzer instance  
 * @param {object} [options] - Configuration options (none currently supported)
 */
function Sentiment(options);

Analysis Result

interface AnalysisResult {
  /** Total sentiment score calculated by summing individual word scores */
  score: number;
  /** Comparative score (score divided by number of tokens) */
  comparative: number;
  /** Array of objects showing which words contributed to the score */
  calculation: Array<{[word: string]: number}>;
  /** All tokens (words/emojis) found in the input text */
  tokens: string[];
  /** Words from input that were found in the sentiment wordlist */
  words: string[];
  /** Words with positive sentiment scores */
  positive: string[];
  /** Words with negative sentiment scores */
  negative: string[];
}

Language Object

interface LanguageObject {
  /** Word-to-score mapping where keys are words and values are sentiment scores (-5 to +5) */
  labels: {[word: string]: number};
  /** Optional custom scoring strategy for handling context and negation */
  scoringStrategy?: ScoringStrategy;
}

interface ScoringStrategy {
  /**
   * Applies contextual scoring logic to individual tokens
   * @param {string[]} tokens - All tokens in the phrase being analyzed
   * @param {number} cursor - Index of the current token being scored
   * @param {number} tokenScore - Base sentiment score for the current token
   * @returns {number} Modified sentiment score for the token
   */
  apply(tokens: string[], cursor: number, tokenScore: number): number;
}

Analysis Options

interface AnalysisOptions {
  /** Two-digit language code for analysis (defaults to 'en') */
  language?: string;
  /** Additional word/score pairs to add or override in the wordlist */
  extras?: {[word: string]: number};
}

Error Handling

The sentiment library handles several error conditions:

  • Invalid language code: Throws Error: No language found: <code> when requesting an unregistered language
  • Missing language labels: Throws Error: language.labels must be defined! when registering a language without required labels
  • Malformed input: Gracefully handles undefined, null, or non-string input by treating it as empty string

Example:

const sentiment = new Sentiment();

try {
  // This will throw an error
  sentiment.analyze('Hello', { language: 'xx' });
} catch (error) {
  console.log(error.message); // "No language found: xx"
}

try {
  // This will throw an error  
  sentiment.registerLanguage('fr', { /* missing labels */ });
} catch (error) {
  console.log(error.message); // "language.labels must be defined!"
}