or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

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

0

# Sentiment

1

2

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.

3

4

## Package Information

5

6

- **Package Name**: sentiment

7

- **Package Type**: npm

8

- **Language**: JavaScript

9

- **Installation**: `npm install sentiment`

10

11

## Core Imports

12

13

```javascript

14

const Sentiment = require('sentiment');

15

```

16

17

ES6 import (if using a transpiler):

18

19

```javascript

20

import Sentiment from 'sentiment';

21

```

22

23

## Basic Usage

24

25

```javascript

26

const Sentiment = require('sentiment');

27

const sentiment = new Sentiment();

28

29

// Analyze sentiment of text

30

const result = sentiment.analyze('Cats are totally amazing!');

31

console.log(result);

32

// {

33

// score: 4,

34

// comparative: 1,

35

// calculation: [{ amazing: 4 }],

36

// tokens: ['cats', 'are', 'totally', 'amazing'],

37

// words: ['amazing'],

38

// positive: ['amazing'],

39

// negative: []

40

// }

41

42

// Override AFINN wordlist

43

const customResult = sentiment.analyze('Cats are stupid.', {

44

extras: { 'cats': 5, 'stupid': -1 }

45

});

46

console.log(customResult.score); // 4 (5 + -1)

47

```

48

49

## Architecture

50

51

Sentiment analysis is built around several key components:

52

53

- **AFINN Wordlist**: Pre-scored word database with values from -5 (negative) to +5 (positive)

54

- **Emoji Support**: Sentiment rankings for emojis integrated into all languages

55

- **Tokenization**: Text preprocessing that splits input into individual words and emojis

56

- **Language System**: Pluggable language support with custom scoring strategies

57

- **Scoring Strategy**: Per-language logic for handling negation, emphasis, and context

58

59

## Capabilities

60

61

### Sentiment Analysis

62

63

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

64

65

```javascript { .api }

66

/**

67

* Performs sentiment analysis on the provided input phrase

68

* @param {string} phrase - Input phrase to analyze

69

* @param {object} [opts] - Analysis options

70

* @param {string} [opts.language='en'] - Language code for analysis (defaults to 'en')

71

* @param {object} [opts.extras={}] - Additional word/score pairs to add or overwrite

72

* @param {function} [callback] - Optional callback function

73

* @returns {object} Sentiment analysis result

74

*/

75

analyze(phrase, opts, callback);

76

```

77

78

**Usage Examples:**

79

80

```javascript

81

const sentiment = new Sentiment();

82

83

// Basic analysis

84

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

85

86

// With language specification

87

const frenchResult = sentiment.analyze('Je suis heureux', {

88

language: 'fr'

89

});

90

91

// With custom word overrides

92

const customResult = sentiment.analyze('This product is okay', {

93

extras: { 'okay': 2 }

94

});

95

96

// With callback (async)

97

sentiment.analyze('Hello world', (err, result) => {

98

console.log(result.score);

99

});

100

```

101

102

### Language Registration

103

104

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

105

106

```javascript { .api }

107

/**

108

* Registers a new language for sentiment analysis

109

* @param {string} languageCode - Two-digit language code (e.g., 'fr', 'es')

110

* @param {object} language - Language configuration object

111

* @param {object} language.labels - Word-to-score mapping for the language

112

* @param {object} [language.scoringStrategy] - Custom scoring strategy for the language

113

*/

114

registerLanguage(languageCode, language);

115

```

116

117

**Usage Examples:**

118

119

```javascript

120

const sentiment = new Sentiment();

121

122

// Register French language

123

sentiment.registerLanguage('fr', {

124

labels: {

125

'bon': 3,

126

'mauvais': -3,

127

'excellent': 5,

128

'horrible': -5

129

}

130

});

131

132

// Register with custom scoring strategy

133

sentiment.registerLanguage('es', {

134

labels: {

135

'bueno': 3,

136

'malo': -3

137

},

138

scoringStrategy: {

139

apply: function(tokens, cursor, tokenScore) {

140

// Custom negation handling for Spanish

141

if (cursor > 0 && tokens[cursor - 1] === 'no') {

142

return -tokenScore;

143

}

144

return tokenScore;

145

}

146

}

147

});

148

149

// Use registered language

150

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

151

```

152

153

## Types

154

155

### Sentiment Constructor

156

157

```javascript { .api }

158

/**

159

* Creates a new Sentiment analyzer instance

160

* @param {object} [options] - Configuration options (none currently supported)

161

*/

162

function Sentiment(options);

163

```

164

165

### Analysis Result

166

167

```javascript { .api }

168

interface AnalysisResult {

169

/** Total sentiment score calculated by summing individual word scores */

170

score: number;

171

/** Comparative score (score divided by number of tokens) */

172

comparative: number;

173

/** Array of objects showing which words contributed to the score */

174

calculation: Array<{[word: string]: number}>;

175

/** All tokens (words/emojis) found in the input text */

176

tokens: string[];

177

/** Words from input that were found in the sentiment wordlist */

178

words: string[];

179

/** Words with positive sentiment scores */

180

positive: string[];

181

/** Words with negative sentiment scores */

182

negative: string[];

183

}

184

```

185

186

### Language Object

187

188

```javascript { .api }

189

interface LanguageObject {

190

/** Word-to-score mapping where keys are words and values are sentiment scores (-5 to +5) */

191

labels: {[word: string]: number};

192

/** Optional custom scoring strategy for handling context and negation */

193

scoringStrategy?: ScoringStrategy;

194

}

195

196

interface ScoringStrategy {

197

/**

198

* Applies contextual scoring logic to individual tokens

199

* @param {string[]} tokens - All tokens in the phrase being analyzed

200

* @param {number} cursor - Index of the current token being scored

201

* @param {number} tokenScore - Base sentiment score for the current token

202

* @returns {number} Modified sentiment score for the token

203

*/

204

apply(tokens: string[], cursor: number, tokenScore: number): number;

205

}

206

```

207

208

### Analysis Options

209

210

```javascript { .api }

211

interface AnalysisOptions {

212

/** Two-digit language code for analysis (defaults to 'en') */

213

language?: string;

214

/** Additional word/score pairs to add or override in the wordlist */

215

extras?: {[word: string]: number};

216

}

217

```

218

219

## Error Handling

220

221

The sentiment library handles several error conditions:

222

223

- **Invalid language code**: Throws `Error: No language found: <code>` when requesting an unregistered language

224

- **Missing language labels**: Throws `Error: language.labels must be defined!` when registering a language without required labels

225

- **Malformed input**: Gracefully handles undefined, null, or non-string input by treating it as empty string

226

227

**Example:**

228

229

```javascript

230

const sentiment = new Sentiment();

231

232

try {

233

// This will throw an error

234

sentiment.analyze('Hello', { language: 'xx' });

235

} catch (error) {

236

console.log(error.message); // "No language found: xx"

237

}

238

239

try {

240

// This will throw an error

241

sentiment.registerLanguage('fr', { /* missing labels */ });

242

} catch (error) {

243

console.log(error.message); // "language.labels must be defined!"

244

}

245

```