JavaScript SDK vs Python SDK: Which One Fits Your Brain?
The Same Brain, Two Different Conversations
Picture this. You just unboxed a Neurosity Crown. Eight EEG channels are about to start streaming your brain's electrical activity at 256 samples per second. You open your laptop, crack your knuckles, and type the words every developer types at the start of something new:
npm install
Or maybe you type pip install.
And right there, before you've written a single line of application logic, you've already made a decision that shapes the entire trajectory of your project. Not because one choice is wrong. But because the Neurosity JavaScript SDK and the Neurosity Python SDK aren't just the same tool in different syntax. They're two different philosophies about what you should do with brain data.
One is built for shipping real-time applications. The other is built for understanding what the data means.
That distinction sounds simple. It's not. And if you pick the wrong one for your use case, you'll feel the friction within the first hour. So let's make sure that doesn't happen.
Why Two SDKs Exist (And Why It's Not Redundant)
Here's a question that seems obvious but actually reveals something important: why would Neurosity build two SDKs instead of just one really good one?
The answer has everything to do with how the JavaScript and Python ecosystems think about data.
JavaScript is an event-driven language. It was born in the browser, raised on callbacks, and matured into a world of Promises, async/await, and reactive streams. When a JavaScript developer hears "real-time brain data," they think: subscriptions, event handlers, UI updates, WebSockets. They want the data flowing through their application like electricity through a circuit, triggering things as it moves.
Python is a computation-oriented language. It was born in academia, raised on numerical computing, and matured into the dominant language for data science and machine learning. When a Python developer hears "real-time brain data," they think: arrays, DataFrames, feature extraction, classification models. They want the data sitting still long enough to analyze it.
These aren't just stylistic preferences. They're fundamentally different relationships with data. And trying to serve both with a single SDK would mean compromising both.
The JavaScript SDK (@neurosity/sdk) leans fully into JavaScript's strengths: RxJS observables for reactive data streams, native browser support for web apps, Node.js support for servers, React Native for mobile. It's the SDK you reach for when you're building something a user interacts with.
The Python SDK leans into Python's strengths: familiar data structures that play nicely with NumPy and pandas, a straightforward API that feels natural in Jupyter notebooks, and a short path from brain data to machine learning pipelines. It's the SDK you reach for when you're trying to learn something from the data.
The Feature Landscape: What Each SDK Actually Gives You
Before we get into philosophy and architecture, let's look at the concrete capabilities. Because sometimes the deciding factor isn't elegance or ecosystem fit. Sometimes it's just "does this SDK do the specific thing I need?"
| Capability | JavaScript SDK | Python SDK (Beta) |
|---|---|---|
| Raw EEG (256Hz, 8 channels) | Yes | Yes |
| Focus score | Yes | Yes |
| Calm score | Yes | Yes |
| Kinesis (mental commands) | Yes | Limited |
| Power-by-band (alpha, beta, etc.) | Yes | Yes |
| Power spectral density | Yes | Yes |
| Signal quality metrics | Yes | Yes |
| Accelerometer data | Yes | Limited |
| Device status and battery | Yes | Yes |
| User authentication | Full (email, token) | Full (email, token) |
| Device management | Full | Basic |
| RxJS reactive streams | Yes (core architecture) | No |
| MCP (AI integration) | Yes | Not yet |
| Web browser support | Yes | No |
| React Native (mobile) | Yes | No |
| Node.js support | Yes | N/A (Python runtime) |
| Jupyter notebook friendly | Possible but awkward | Yes (native fit) |
| NumPy/pandas integration | No | Natural |
| TypeScript definitions | Yes (first-class) | N/A |
A few things jump out from that table.
The JavaScript SDK has a wider feature set. It covers every data stream the Crown produces, handles device management comprehensively, and is the exclusive path to MCP integration for connecting brain data to AI tools like Claude and ChatGPT. If a feature exists on the Crown, the JavaScript SDK almost certainly exposes it.
The Python SDK covers the core data streams, the ones you actually need for analysis and ML, but it's lighter on device management and doesn't yet support some of the more application-oriented features. That's not a shortcoming. It's a reflection of what Python developers typically need. You're not usually building a device management UI in Python. You're analyzing brainwave patterns.
The real gap to be aware of: MCP. If your project involves AI integration, that currently means JavaScript. The Python SDK doesn't have native MCP support yet. You can build bridges (Python is great at HTTP, after all), but the turnkey integration lives in the JS world.
The Code: Same Task, Different Universes
Nothing clarifies the difference between two SDKs like seeing them do the same thing. Let's look at the most common starting point: subscribing to focus scores from the Crown.
JavaScript SDK: Reactive Streams
import { Neurosity } from "@neurosity/sdk";
const neurosity = new Neurosity({ deviceId: "YOUR_DEVICE_ID" });
await neurosity.login({ email: "you@email.com", password: "pass" });
neurosity.focus().subscribe((focus) => {
console.log("Focus:", focus.probability);
});
Five lines from import to streaming brain data. The .subscribe() call sets up a persistent reactive stream. Every time the Crown computes a new focus score (roughly every 4 seconds), your callback fires. You didn't poll for data. You didn't set up a timer. The data comes to you.
And because it's built on RxJS, you get the entire RxJS operator library for free. Want to only react when focus drops below 0.3? Add a .pipe(filter(...)). Want to average focus over the last 30 seconds? Add a .pipe(bufferTime(...), map(...)). Want to combine focus and calm into a composite score? Use combineLatest. The reactive model isn't just convenient. It's composable.
Python SDK: Direct and Familiar
from neurosity import NeurositySDK
neurosity = NeurositySDK({
"device_id": "YOUR_DEVICE_ID"
})
neurosity.login({
"email": "you@email.com",
"password": "pass"
})
def on_focus(data):
print(f"Focus: {data['probability']}")
unsubscribe = neurosity.focus(on_focus)
Similar line count. Similar structure. But the mental model is different. There's no observable. There's a callback function that receives data, and an unsubscribe handle you call when you're done. It's the pattern Python developers already know from event-based libraries.
The real difference shows up in what you do with the data next. In JavaScript, you pipe it through operators and into your UI framework. In Python, you probably want to collect it into a list or a DataFrame:
import pandas as pd
focus_data = []
def collect_focus(data):
focus_data.append({
"timestamp": data["timestamp"],
"probability": data["probability"]
})
unsubscribe = neurosity.focus(collect_focus)
# Later, after collecting data...
df = pd.DataFrame(focus_data)
print(df.describe())
Six lines and you've gone from brain data to a pandas DataFrame with full statistical summaries. Try doing that in JavaScript. You can, technically. But it'll feel like hammering a screw.
The Ecosystem Effect: Why Your Language Choice Echoes
Here's the thing about picking an SDK that most comparison guides miss: you're not just picking a library. You're picking an entire ecosystem of tools that will surround your project.
When you choose the JavaScript SDK, you inherit access to: React and Next.js for building web-based neurofeedback dashboards. Three.js and D3.js for real-time brain data visualization. Express and Fastify for building brain-data APIs. Electron for desktop applications. React Native for mobile apps that read your mind (well, your brainwaves). Socket.io for broadcasting brain data to multiple clients in real time. And the entire npm ecosystem of 2+ million packages.
The JavaScript SDK was designed to fit into this world. RxJS observables pipe directly into React component state. TypeScript definitions give you autocomplete for every data structure the Crown produces. The authentication system works the way JavaScript developers expect authentication to work.
When you choose the Python SDK, you inherit access to: NumPy and SciPy for signal processing and spectral analysis. pandas for structured data manipulation. scikit-learn for classical ML on brain features. TensorFlow and PyTorch for deep learning on EEG data. MNE-Python for research-grade EEG analysis (you can bridge data into MNE's format). matplotlib and seaborn for publication-quality visualizations. Jupyter notebooks for interactive exploration.
The Python SDK was designed to fit into this world. Data comes back in structures that convert to NumPy arrays without ceremony. The API feels like every other well-designed Python data library you've used. The workflow of "subscribe, collect, analyze" maps directly to how data scientists already work.
This ecosystem effect is the real reason the two SDKs exist. A single "universal" SDK would have to pick one set of conventions, and half the developer population would feel like they were writing code with oven mitts on.
Real-Time Applications vs. Data Science: The Fork in the Road
Let's get specific about the two major categories of Crown projects and which SDK dominates each.
Building Real-Time Applications (JavaScript Wins)
If your project involves any of these, the JavaScript SDK is almost certainly the right choice:
- A web dashboard showing live brain data
- A neurofeedback app that plays audio/visual feedback based on brain state
- A productivity tool that tracks focus over the workday
- An AI assistant that adapts based on your cognitive state (MCP)
- A mobile app built with React Native
- A multiplayer experience where multiple users share brain data
- Any project where a non-technical user interacts with the output
The JavaScript SDK's reactive architecture was built for these exact scenarios. RxJS observables mean your UI stays in sync with brain data without you managing state manually. The subscription model means you're always working with the latest data, not polling a buffer. And the platform reach (browsers, Node, React Native) means you can deploy wherever your users are.
Here's a tiny example that shows the power of the reactive model. Say you want to trigger an alert only when a user's focus drops below 0.3 for more than 10 consecutive seconds:
import { filter, bufferTime } from "rxjs/operators";
neurosity.focus().pipe(
bufferTime(10000),
filter(readings => readings.length > 0),
filter(readings =>
readings.every(r => r.probability < 0.3)
)
).subscribe(() => {
triggerFocusAlert();
});
That's a complex temporal condition expressed in a handful of lines. No timers. No state variables. No "last ten seconds" buffer you manage yourself. RxJS handles the windowing, filtering, and timing. You just describe what you care about.
Doing the same thing in Python is absolutely possible. But you'd be building the buffering logic yourself, managing timestamps, and probably running a background thread. It's more code, more state, and more surface area for bugs.

Data Science and Machine Learning (Python Wins)
If your project involves any of these, the Python SDK is the natural fit:
- Exploratory analysis of your own brainwave patterns
- Training a custom ML classifier on EEG features
- Building a brain-state detection model
- Academic research or replicating published EEG studies
- Generating visualizations for a paper or presentation
- Comparing spectral features across different cognitive tasks
- Batch processing recorded brain data
Python's dominance in data science isn't accidental. The language, the libraries, and the workflows were all co-designed for exactly this kind of work. And the Python SDK puts Crown data directly into that world.
Here's a practical example. Suppose you want to record 5 minutes of power-by-band data during a focus session, then analyze which frequency bands correlate most strongly with high focus periods:
import pandas as pd
import numpy as np
from neurosity import NeurositySDK
records = []
def collect(data):
records.append({
"timestamp": data["timestamp"],
"alpha": np.mean(data["alpha"]),
"beta": np.mean(data["beta"]),
"theta": np.mean(data["theta"]),
"gamma": np.mean(data["gamma"])
})
neurosity.brainwaves("powerByBand", collect)
# After 5 minutes of collection...
df = pd.DataFrame(records)
print(df.corr()) # Correlation matrix across bands
From brain data to correlation matrix in a few lines. No data format conversion. No file I/O. No language bridging. The data flows from the Crown to the Python SDK to pandas to whatever analysis you want to run next.
This is where the Python SDK's beta status actually matters least. The core data streams (raw EEG, power-by-band, focus, calm) are exactly what data science projects need. The features the Python SDK is missing (MCP, advanced device management, React Native support) are application features that data science workflows rarely require.
Platform Support: Where Your Code Can Actually Run
This one's straightforward but important. Where your code runs determines which users can use what you build.
| Platform | JavaScript SDK | Python SDK |
|---|---|---|
| Chrome / Firefox / Safari | Yes (full support) | No |
| Node.js server | Yes (full support) | N/A |
| React Native (iOS/Android) | Yes | No |
| Electron desktop app | Yes | No |
| Local Python script | No | Yes |
| Jupyter Notebook | Awkward | Natural fit |
| Google Colab | No | Yes |
| Raspberry Pi | Yes (Node.js) | Yes |
| AWS Lambda / Cloud Functions | Yes | Yes |
| Docker container | Yes | Yes |
The JavaScript SDK's platform story is about reach. Browsers, servers, mobile, desktop. If it runs JavaScript, it can talk to the Crown.
The Python SDK's platform story is about environment fit. Local development, notebooks, cloud compute, research servers. If it's a place where data scientists work, the Python SDK feels at home.
One scenario worth calling out: Jupyter notebooks. If you do any kind of interactive data exploration (and if you're doing data science, you do), the Python SDK in a Jupyter notebook is genuinely pleasant. You subscribe to data in one cell, collect it while you sip coffee, then analyze and visualize it in the next cell. The iterative, cell-by-cell workflow maps perfectly to the "collect, then analyze" pattern of the Python SDK.
The JavaScript SDK in a Jupyter notebook (via the IJavaScript kernel) technically works. But it's like wearing a tuxedo to go hiking. Technically possible. Not exactly what it was designed for.
Community and Documentation: Where You Go When Things Break
Let's be honest about the state of documentation and community for each SDK, because this is where beta status really shows.
JavaScript SDK: Mature and Well-Traveled
The JavaScript SDK documentation at docs.neurosity.co is comprehensive. Every data stream has its own page with code examples. Authentication flows are documented with edge cases covered. TypeScript definitions mean your IDE gives you autocomplete and type checking before you even read the docs.
The community around the JavaScript SDK is active. The Neurosity Discord has channels where developers share projects, ask questions, and get responses from both the community and Neurosity's founders. There are example projects on GitHub. There are community blog posts. There's a track record of real applications built and shipped.
When you hit a wall with the JavaScript SDK, you'll almost certainly find someone who's hit the same wall before you.
Python SDK: Growing, With Gaps
The Python SDK documentation exists but is less extensive. The core API is documented, and the basic patterns (connect, authenticate, subscribe) are clear. But the edge cases, the troubleshooting guides, the "here's what to do when X goes wrong" content, that's still being built.
The community around the Python SDK is smaller, which is expected for a beta. You'll find Python developers on the same Discord, and they're helpful. But the pool of "someone has already solved this exact problem" answers is shallower.
This isn't a dealbreaker. It's a tradeoff. If you're comfortable reading source code when the docs don't cover your question, and if you're the kind of developer who enjoys being early to a platform (with the influence over its direction that comes with that), the Python SDK's beta status is an opportunity, not a risk.
Many developers use a hybrid approach: the JavaScript SDK for their production application and the Python SDK for their analysis pipeline. Your Node.js server handles real-time brain data subscriptions, authentication, and user-facing features. Your Python scripts handle batch analysis, model training, and data exploration. The Crown feeds both through the same cloud infrastructure. You get the JavaScript SDK's maturity for the parts users see, and Python's analytical power for the parts they don't.
The "I Had No Idea" Moment: RxJS Is Secretly a Superpower for Brain Data
Here's something that most developers don't appreciate until they're deep into a BCI project: brain data is one of the best possible use cases for reactive programming. And the JavaScript SDK's decision to build on RxJS isn't just a stylistic preference. It solves a category of problems that imperative code handles poorly.
Think about what brain data actually is. It's a continuous, multi-channel, time-series stream that never stops. While the Crown is on your head, data is always flowing. You don't request brain data the way you request an API endpoint. You open a firehose and decide what to pay attention to.
RxJS was designed for exactly this. Its entire mental model is built around continuous streams of events that you can transform, combine, filter, and compose. Here's why that matters for BCI development specifically:
Multi-stream composition. The Crown produces multiple simultaneous data streams: raw EEG, focus, calm, accelerometer, signal quality. In a real application, you often need to combine them. "Show me focus score, but only when signal quality is above 0.8" is a one-liner with RxJS's combineLatest and filter. In imperative code, you're managing multiple callback registrations, synchronizing timestamps, and maintaining shared state. It works, but it's fragile.
Backpressure and throttling. Raw EEG at 256Hz means 256 data events per second per channel. If your UI can only render at 60fps, you need to downsample. RxJS operators like throttleTime, sampleTime, and bufferTime handle this declaratively. Without them, you're writing rate-limiting logic by hand, and getting it right in an async environment is trickier than it sounds.
Automatic cleanup. RxJS subscriptions have built-in lifecycle management. Unsubscribe and everything cleans up: the data stream, the WebSocket connection, the memory buffers. In a React app, you unsubscribe in your useEffect cleanup function, and you never leak a brain data connection. This sounds mundane until you've debugged a memory leak caused by a brain data subscription that outlived the component that created it.
Python has reactive libraries (RxPY exists), but they're not part of the language's DNA the way RxJS is part of JavaScript's. The Python SDK made the right call by not forcing reactive patterns onto a language that thinks differently. But if your project needs sophisticated stream processing, the JavaScript SDK's RxJS foundation is genuinely hard to replicate.
Decision Matrix: Your Project, Your SDK
Let's make this practical. Here are the most common project types and the SDK that fits each one.
"I want to build a focus-tracking web app." JavaScript SDK. Browser support, reactive UI updates, authentication, and the full feature set. This is the SDK's home turf.
"I want to analyze my brainwave patterns in a Jupyter notebook." Python SDK. Subscribe, collect data into a DataFrame, analyze and visualize. This is exactly what the Python SDK was built for.
"I want to build a mobile app that responds to brain state." JavaScript SDK. React Native support means you can ship to iOS and Android from a single codebase with full Crown integration.
"I want to train a custom ML model on EEG data." Python SDK. Direct path to NumPy, scikit-learn, TensorFlow, and PyTorch. No language bridging required.
"I want my AI assistant to adapt based on my cognitive state." JavaScript SDK. MCP integration is exclusive to the JavaScript ecosystem right now. It's the only turnkey path from brain data to Claude or ChatGPT.
"I want to prototype something quickly to see if my idea works." This depends on which language you think in. If you're a JavaScript developer, use the JavaScript SDK. If you're a Python developer, use the Python SDK. Prototyping speed comes from using the language you already know, not from the SDK's feature set.
"I want to build a research tool that records and analyzes EEG data." Python SDK for the analysis pipeline. Consider the JavaScript SDK (or BrainFlow) for the recording layer if you need a user-facing interface for session management.
The Beta Question: Should You Bet on the Python SDK Today?
Let's address this directly, because "beta" is a word that means different things to different developers.
The Python SDK is beta in the sense that its feature surface is still growing, its documentation is still maturing, and its API might change in ways that require you to update your code. It is not beta in the sense that it's unreliable or crashes randomly. The core functionality, connecting to the Crown, authenticating, and subscribing to brain data streams, works.
If you're building a production application with paying users who depend on stability, the JavaScript SDK is the safer choice today. It's battle-tested, fully documented, and its API surface is stable.
If you're building a research tool, a personal project, a proof of concept, or a machine learning pipeline, the Python SDK's beta status is barely relevant. You're not shipping to users who need five-nines uptime. You're exploring data. The SDK does that well.
And there's an underrated advantage to adopting a beta SDK: you get to shape it. The Neurosity team actively solicits feedback from Python SDK users. Feature requests made today become capabilities available tomorrow. If you've ever wished you could influence the design of a tool you use daily, this is your chance.
Where This Is All Heading
Step back for a moment and think about what it means that a brain-computer interface ships with both a JavaScript and a Python SDK.
Ten years ago, the idea of a consumer EEG device with any official SDK was ambitious. The BCI world was dominated by proprietary software packages that cost thousands of dollars, ran only on Windows, and exported data in formats that required specialized tools to read. "Building a brain-computer interface" meant getting a PhD and a grant, not running npm install.
Today, a developer who has never taken a neuroscience class can subscribe to their own brainwaves in five lines of code, in the language they already know. The JavaScript SDK puts brain data into web apps, mobile apps, and AI tools. The Python SDK puts brain data into machine learning pipelines, research notebooks, and statistical analyses.
That's two different on-ramps to the same profound capability: software that responds to thought.
The question isn't really "JavaScript or Python." The question is what you want to build with access to the most complex signal in the known universe. The SDK is just the door. What matters is what you do once you walk through it.
And honestly? The most interesting projects will probably walk through both.

