
Blazor has been one of the most requested platforms from our community over the past few years.
If you’re building line-of-business apps in .NET, internal dashboards, scientific tools, fintech systems, or telemetry visualization platforms — chances are you’ve looked at Blazor and thought: “I wish I could use SciChart here.”
Today, we’re excited to announce: SciChart for Blazor is now in Alpha.
Why We Built SciChart for Blazor
At SciChart, our mission has always been consistent:
Deliver the fastest, most powerful, most flexible data visualization tools across platforms.
We support WPF, JavaScript, iOS, macOS and Android. Increasingly, customers are standardizing on Blazor for:
- Enterprise dashboards
- Internal data tools
- Scientific and engineering software
- Financial and trading platforms
- Industrial monitoring systems
Blazor gives .NET developers a modern component model with Razor syntax, C# everywhere, and WebAssembly deployment.
But high-performance charts in Blazor?
That’s been the missing piece, until now…
What We’ve Done
We’ve created a NuGet package that wraps SciChart.js and exposes a Razor-style component syntax for building charts directly in Blazor. Both Blazor Wasm and Server-side Blazor are supported.
Under the hood:
- Rendering is powered by SciChart.js (WebGL, WebAssembly)
- Performance is GPU-accelerated
- The Blazor layer provides a clean, .NET-native developer experience
If you’re already using SciChart.js (have an active license), you can use SciChart for Blazor. If you’re trialling it out, SciChart.js ships with a free community license to allow you to get started.
It’s the same engine, same performance and same capabilities as SciChart.js, just a different programming model.
Architecture Overview
Here’s how it works conceptually:
Blazor (.NET / C#)
↓
Blazor Component Layer (Razor)
↓
Interop Layer (Optimised for data transfer)
↓
SciChart.js (WebAssembly + WebGL)
↓
GPU
We didn’t reimplement a charting engine in C#, we exposed the most powerful WebGL charting engine available to Blazor developers.
Performance Challenges We Solved
Blazor WebAssembly introduces some unique technical challenges when working with high-performance graphics engines.
We had to solve two major problems.
#1 – Memory Management
SciChart.js uses WebAssembly memory internally. Blazor WebAssembly also runs in WebAssembly using the Mono runtime to deliver .NET.
That means you have two memory spaces, and if you don’t manage them properly, you leak memory very quickly.
We solved this using:
IAsyncDisposable- Finalizer pattern
- Explicit deletion of underlying WebAssembly objects in SciChart.js
Example pattern of how SciChartSurfaceis disposed, and how this passes disposal down to child objects.
public async ValueTask DisposeAsync()
{
if (_sciChartSurface != null && _module != null)
await _module.InvokeVoidAsync("deleteSciChartSurface", DivElementId, _sciChartSurface);
foreach (var item in XAxes) item.Dispose();
foreach (var item in YAxes) item.Dispose();
foreach (var item in ChartModifiers) item.Dispose();
foreach (var item in Annotations) item.Dispose();
foreach (var item in RenderableSeries) item.Dispose();
foreach (var item in StackedCollections) item.Dispose();
_sciChartSurfaceDotNetRef?.Dispose();
if (_module != null)
await _module.DisposeAsync();
}This ensures:
- Charts are cleaned up correctly
- WebAssembly memory is freed
- GPU resources are released
- Long-running dashboards remain stable
Memory discipline is non-negotiable when you’re building serious applications.
#2 Real-Time Data Performance
This was the hard problem to solve.
Blazor WebAssembly normally communicates with JavaScript via JSON serialization. So every other JavaScript chart library that has been enabled with Blazor relies on this very slow path for communicating data to/from the JS chart.
That’s fine for configuration objects, but it’s terrible for high-frequency streaming data.
Imagine pushing 100k data-points per second, across the .NET -> JS boundary, via JSON serialization/deserialization.
It’s slow. It allocates and it stutters, so we didn’t do that!
Instead We Invented a Direct Wasm-to-Wasm Pointer Copy Technique
Both Blazor and SciChart.js run in WebAssembly memory, so we bypass JSON entirely.
SciChart.Blazor performs:
- Direct memory pointer access
- Wasm to Wasm memory copy
- Has zero JSON serialization
- .. and no intermediate allocations
Effectively:
.NET Blazor Wasm Memory → Direct Pointer Copy → SciChart Wasm Memory
This allows real-time updates at speeds comparable to native SciChart.js.
This is what makes real-time charts viable in Blazor. So, it’s not a toy demo, but production viable.
Supported Chart Types
SciChart for Blazor is currently in Alpha, and built on top of SciChart.js v5.0.178. We will be updating this to Beta and a full release shortly.
SciChart.Blazor currently supports the following features of SciChart.js:
2D Chart Series Supported by SciChart.Blazor
- Line charts
FastLineRenderableSeries - Spline (smoothed) line charts
SplineLineRenderableSeries - Scatter charts
XyScatterRenderableSeries - Mountain / Area charts
FastMountainRenderableSeries - Column / Bar charts
FastColumnRenderableSeries - Band charts (high-low range)
FastBandRenderableSeries - Bubble charts
FastBubbleRenderableSeries - Candlestick charts
FastCandlestickRenderableSeries - OHLC charts
FastOhlcRenderableSeries - Impulse or Stem charts
FastImpulseRenderableSeries - Error bars on charts
FastErrorBarsRenderableSeries - 2D Heatmap charts
UniformHeatmapRenderableSeries - Stacked column charts
StackedColumnCollection - Stacked mountain charts
StackedMountainCollection
All with real-time dynamic updates as well as static charts via our DataSeries API.
Axis Types Supported by SciChart.Blazor
- Numeric value axis
NumericAxis - Category axis
CategoryAxis - Date axis
DateTimeNumericAxis
Zoom, Pan & Legend Interactions / Behaviors Supported by SciChart.Blazor
- Mousewheel zoom to pan or scroll
MouseWheelZoomModifier - Drag to pan
ZoomPanModifier - Drag to zoom a region
RubberBandXyZoomModifier - Cursor tooltips
RolloverModifier - Double-click to fit chart
ZoomExtentsModifier - Drag axis to zoom, scale or pan
XAxisDragModifier/YAxisDragModifier - Click to select datapoints
DataPointSelectionModifier - Interactive Chart legends
LegendModifier
Annotation Types Supported by SciChart.Blazor
- Lines
LineAnnotation - Lines with arrows
LineArrowAnnotation - Text labels
NativeTextAnnotation/TextAnnotation - Axis markers
AxisMarkerAnnotation - Horizontal / Vertical Lines which stretch to fit
HorizontalLineAnnotation/VerticalLineAnnotation - Box / rectangles
BoxAnnotation - Custom shapes, markers via SVG
CustomAnnotation>
The list will expand during beta.
For the most up-to-date information, see https://github.com/abtsoftware/scichart.blazor.examples
The README contains: Setup instructions, supported chart types, API examples, events and dynamic updates examples.
Razor Syntax Example
Blazor developers expect declarative components, so we made charts feel natural in Razor.
Example: Annotations Demo
<SciChartSurface>
<XAxes/>
<NumericAxis/>
</XAxes/>
<YAxes/>
<NumericAxis/>
</YAxes/>
<-- Databinding possible to items in code behind -->
<TextAnnotation @key="ann.Id"
Id="@ann.Id"
X1="@ann.X1" Y1="@ann.Y1"
Text="@ann.Text"
TextColor="@ann.TextColor"
FontSize="@ann.FontSize"
FontFamily="@ann.FontFamily"
FontWeight="@ann.FontWeight"
Background="@ann.Background"
Padding="@ann.Padding"
XCoordShift="@ann.XCoordShift"
YCoordShift="@ann.YCoordShift"
VerticalAnchorPoint="@ann.VerticalAnchorPoint"
HorizontalAnchorPoint="@ann.HorizontalAnchorPoint"
IsEditable="@ann.IsEditable"/>
</SciChartSurface>
Behind the scenes:
- Components such as
TextAnnotationorNumericAxismap to SciChart.js objects - Lifecycle is managed via
IAsyncDisposable - Updates are synchronized efficiently
- Data-binding is possible to items created in code behind
You can view the full demo here:
Annotations demo SciChart.Blazor:
github.com/ABTSoftware/SciChart.Blazor.Examples/blob/main/WasmDemo/Pages/AnnotationsDemo.razor
Example: Real-Time Dynamic Line Series
Given a chart declared in *.razor as follows:
<SciChartSurface @ref="_sciChartRef" HeightAspect="2" WidthAspect="3" OnSciChartSurfaceRendered="HandleSurfaceRendered">
<XAxes>
<NumericAxis AutoRange="@_autoRange" />
</XAxes>
<YAxes>
<NumericAxis AutoRange="@_autoRange" />
</YAxes>
<FastLineRenderableSeries
Id="series_1"
Stroke="#FF6600"
StrokeThickness="2"
SeriesName="Series 1">
<XyDataSeries @ref="_xyDataSeriesLine1Ref" ContainsNaN="false" IsSorted="true" />
</FastLineRenderableSeries>
<FastLineRenderableSeries
Id="series_2"
Stroke="#50C7E0"
StrokeThickness="2"
SeriesName="Series 2">
<XyDataSeries @ref="_xyDataSeriesLine2Ref" ContainsNaN="false" IsSorted="true" />
</FastLineRenderableSeries>
<FastLineRenderableSeries
Id="series_3"
Stroke="#E26565"
StrokeThickness="2"
SeriesName="Series 3">
<XyDataSeries @ref="_xyDataSeriesLine3Ref" ContainsNaN="false" IsSorted="true" />
</FastLineRenderableSeries>
<MouseWheelZoomModifier />
<XAxisDragModifier />
<YAxisDragModifier />
<ZoomExtentsModifier />
<LegendModifier />
</SciChartSurface>With FastLineRenderableSeriesand XyDataSeries declared in Razor syntax, we can then append data to the series (stream data) in real-time as follows:
private async void OnTimerElapsed(object? sender, ElapsedEventArgs e)
{
if (!_isReadyForNextUpdate)
{
return;
}
_isReadyForNextUpdate = false;
// each data object has .xValues as double[], .yValues as double[]
// memory is declared / accessed in .NET runtime (Blazor wasm memory)
var data1 = _generator1.GetRandomWalkSeries(_numberOfPointsPerTimerTick);
var data2 = _generator2.GetRandomWalkSeries(_numberOfPointsPerTimerTick);
var data3 = _generator3.GetRandomWalkSeries(_numberOfPointsPerTimerTick);
await InvokeAsync(async () =>
{
// Fast copy to SciChart.js (wasm to wasm pointer copy)
await _xyDataSeriesLine1Ref.AppendRangeByPointer(data1.xValues, data1.yValues);
await _xyDataSeriesLine2Ref.AppendRangeByPointer(data2.xValues, data2.yValues);
await _xyDataSeriesLine3Ref.AppendRangeByPointer(data3.xValues, data3.yValues);
});
}With the direct Wasm pointer copy optimization:
- There is no JSON bottleneck
- No per-point serialization / deserialization
- This unlocks smooth streaming
You can view the full example here:
Events & Dynamic Updates
Blazor developers need event callbacks, dynamic chart updates, runtime axis or property changes, series visibility and styling toggling.
These are supported via:
- C# event handlers
- State-driven updates
- Reactive patterns
The README covers the available events and usage patterns.
Who Is This For?
SciChart for Blazor is ideal if you’re building engineering dashboards, financial applications, scientific tools, industrial monitoring systems or telemetry visualization platforms,
If you need to visualize millions of data-points, real-time streaming of data and WebGL accelerated professional grade charting, Blazor now has a serious answer.
Alpha Status
This is an Alpha release. SciChart for Blazor is in active development and requires testing and feedback from the community.
That means the API may evolve. Some chart types still to be added (particularly 3D charts), and the documentation and examples need expanding.
Feedback is very welcome. Please do this via the Github Issues for SciChart.Blazor.Examples.
We built this because you asked for it. We’d love to hear your input to shape it!
How to Try It
- Visit the examples repo: https://github.com/abtsoftware/scichart.blazor.examples
- Follow the setup instructions in the README
- Run the WebAssembly demo
- Experiment
- Tell us what you think!
What’s Next?
Planned improvements include:
- More chart types, adding 3D chart support
- Performance profiling tools
- Extended modifier support
- Improved event system
This is just the beginning.
If you’re building in Blazor and need high-performance charts SciChart for Blazor is here!
And this time, it’s not a compromise. You get the real SciChart.js engine, running at full speed and actively maintained by our team.
Related Posts

