Category: All posts
May 01, 2025
Posted by
Jônatas Davi Paganini
Today, we're excited to announce that we're expanding our ecosystem support, making it easier to connect PostgreSQL and TypeScript when using TimescaleDB. This expansion is also available for other programming languages. While PostgreSQL has always been language-agnostic, we recognize that each developer community has unique needs, patterns, and expectations regarding database integration.
Better database integration streamlines data access, enhances performance, and improves scalability, so our mission is simple: meet developers where they are and make TimescaleDB a natural extension of their existing PostgreSQL workflow—regardless of their programming language of choice.
TypeScript is a strongly typed superset of JavaScript with excellent tooling support, static type checking, and enhanced development features. It provides enhanced developer experience through early error detection, superior code organization, and seamless integration with modern frameworks.
TypeScript's connection with PostgreSQL through TimescaleDB offers developers a type-safe, maintainable approach to building data-driven applications with enhanced tooling support, static type checking, and seamless integration with modern frameworks.
Daniel Starns leads our TypeScript and PostgreSQL integration. He previously worked on the core of Prisma ORM. To build the timescaledb-ts package, Daniel implemented feature parity with the timescaledb-ruby features (learn more about the TimescaleDB Ruby gem here) but followed the TypeScript style. He implemented the TimescaleDB functionality in a core library that wraps SQL and extra packages for TypeORM and Sequelize.
Getting started with TypeORM and TimescaleDB is straightforward; simply install our integration alongside your TypeORM installation:
$ npm install typeorm @timescaledb/typeorm
Then, you can use our custom TypeScript Decorators to annotate any common generic model:
import { Entity, PrimaryColumn } from 'typeorm';
+ import { Hypertable, TimeColumn } from '@timescaledb/typeorm';
+ @Hypertable({ ... })
@Entity('page_loads')
export class PageLoad {
@PrimaryColumn({ type: 'varchar' })
user_agent!: string;
+ @TimeColumn()
time!: Date;
}
The highlighted code above is what users need to provide to TypeORM to connect to TimescaleDB. The interaction behind the scenes handles the rest, such as auto-migrating hypertables.
There are several other expressive decorators, such as @ContinuousAggregate
and @Rollup
, that let you express and fine-tune aggregation views on top of time windows. If you find the TypeScript package helpful to connect to your PostgreSQL database, don’t forget to leave us a GitHub star! 🌟
To learn more, follow the guides in our source:
Outside of the engineering work, the TypeScript team has connected with the TypeORM maintainers. They have a pinned post on their Discord server and collaborated in a call with the maintainers. From here, the goal is to collaborate further with the community, create more documentation and examples, perform live streams, and educate developers through community events.
Beyond TypeScript, we've expanded our integration efforts to include several other languages. We began this journey with Ruby, creating a deeply integrated experience that feels natural to Ruby and Rails developers, including:
Building on this foundation, we've already expanded to PHP, thanks to Tobias Petry.
This approach isn't limited to specific languages—it establishes a blueprint for how TimescaleDB can integrate seamlessly with any language ecosystem through both official packages and community-led initiatives.
Let's examine the setup for each language:
import { Entity, PrimaryColumn } from 'typeorm';
import { Hypertable, TimeColumn } from '@timescaledb/typeorm';
@Entity('page_loads')
@Hypertable({
compression: { // Optional compression
compress: true,
compress_orderby: 'time',
compress_segmentby: 'user_agent',
policy: {
schedule_interval: '7 days',
},
},
})
export class PageLoad {
@PrimaryColumn({ name: 'user_agent', type: 'varchar' })
userAgent!: string;
@TimeColumn()
time!: Date;
}
hypertable_options = {
time_column: 'created_at', # partition data by this column
chunk_time_interval: '1 day', # create a new table for each day
compress_segmentby: 'identifier', # columnar compression key
compress_after: '7 days', # start compression after 7 days
compress_orderby: 'created_at DESC', # compression order
drop_after: '6 months' # delete data after 6 months
}
create_table(:events, id: false, hypertable: hypertable_options) do |t|
t.timestamptz :created_at, null: false
t.string :identifier, null: false
t.jsonb :payload
end
return new class extends Migration
{
public function up(): void
{
Schema::createExtensionIfNotExists('timescaledb');
Schema::create('visits', function (Blueprint $table) {
$table->identity();
$table->bigInteger('website_id');
$table->text('url');
$table->float('duration');
$table->timestampTz('created_at');
$table->primary(['id', 'created_at']);
$table->index(['website_id', 'created_at']);
$table->timescale(
new CreateHypertable('created_at', '1 day'),
new CreateReorderPolicyByIndex('website_id', 'created_at'),
new EnableCompression(segmentBy: 'website_id'),
new CreateCompressionPolicy('3 days'),
new CreateRetentionPolicy('1 year'),
new EnableChunkSkipping('id'),
);
});
Schema::continuousAggregate('visits_agg', function(CaggBlueprint $table) {
$table->as("
SELECT
time_bucket('1 hour', created_at) AS bucket,
website_id,
url,
SUM(duration) AS duration
FROM visits
GROUP BY bucket, website_id, url
");
$table->realtime();
$table->index(['website_id','url']);
$table->timescale(
new CreateRefreshPolicy('5 minutes', '1 days', '2 hours'),
new EnableCompression(),
new CreateCompressionPolicy('2 days'),
);
});
}
};
While TimescaleDB works with any language that connects to PostgreSQL, we believe in going beyond basic compatibility. Language-specific integrations offer significant advantages:
Our goal isn't merely compatibility with your technology stack—we aim to become an essential, natural extension of it.
Want to create your own integration? Check out our comprehensive integration guide.
We're actively seeking developers interested in building and maintaining TimescaleDB integrations for their language communities. Whether you're passionate about Python, Go, Rust, PHP, JavaScript, Java, .NET, or any other ecosystem, we want to support your efforts.
Here's what we offer to community integration maintainers:
If you're interested, book a Technical Office Hours call with me (Jônatas, developer advocate at Timescale), and let's begin the conversation!
We're approaching this ecosystem expansion methodically. Throughout this process, you can expect to see us document our approach, share best practices, and create reusable patterns that make TimescaleDB integration consistent across languages while remaining idiomatic to each.
We're committed to fostering a strong community around TimescaleDB and encouraging broader ecosystem development. Here's how we plan to engage and support developers:
Through these initiatives, we aim to build an inclusive community where developers can learn, collaborate, and create innovative applications with TimescaleDB.
At Timescale, we believe real-time analytics is essential for any data-driven business, which means time-series data is everywhere. Developers across all language communities deserve high-quality tools for handling this demanding workload. By expanding our ecosystem support and embracing community-led integrations, we're creating a more inclusive and powerful platform.
Join us in this mission! Here’s how you can get involved:
Are you building an integration for TimescaleDB in your preferred language? We'd love to hear about it! Share your project or reach out to our Ecosystem team directly.