Updates

Simplified Field Types

When developing software, choosing the right programming language for the job is the most critical decision, as, depending on your choice, the efficiency and reliability of your application (and also your engineering team) can vary drastically. Once this decision has been made, the real work can begin, which, in addition to building out the application itself, also requires selecting potential tools and services to integrate. Since those often cater to many different programming languages at once (not just the one you’ve selected), you then end up adopting additional languages just for those purposes. At RONIN, we strive to provide developers with the fastest and most intuitive database for web applications. As part of that, we consider it essential to align with your existing development stack, instead of imposing new syntaxes and language paradigms on you.

Simplified Field Types

When developing software, choosing the right programming language for the job is the most critical decision, as, depending on your choice, the efficiency and reliability of your application (and also your engineering team) can vary drastically. Once this decision has been made, the real work can begin, which, in addition to building out the application itself, also requires selecting potential tools and services to integrate. Since those often cater to many different programming languages at once (not just the one you’ve selected), you then end up adopting additional languages just for those purposes. At RONIN, we strive to provide developers with the fastest and most intuitive database for web applications. As part of that, we consider it essential to align with your existing development stack, instead of imposing new syntaxes and language paradigms on you.

Teams within Spaces

Building trust with your customers is not only a matter of ensuring that your application behaves in a predictable, reliable, and secure manner, but also enforcing and upholding those same standards internally, within your team. Even the most secure applications remain vulnerable if the team, which manages the application , isn’t secure as well. Specifically, if everyone on the team has access to all resources, even if they don’t actually need to access them, it becomes very hard to predict the worst-case vulnerability scenario and prepare against it. At the same time, however, it is essential not to slow your team down and avoid imposing unnecessary restrictions that could affect your team’s velocity.

Teams within Spaces

Building trust with your customers is not only a matter of ensuring that your application behaves in a predictable, reliable, and secure manner, but also enforcing and upholding those same standards internally, within your team. Even the most secure applications remain vulnerable if the team, which manages the application , isn’t secure as well. Specifically, if everyone on the team has access to all resources, even if they don’t actually need to access them, it becomes very hard to predict the worst-case vulnerability scenario and prepare against it. At the same time, however, it is essential not to slow your team down and avoid imposing unnecessary restrictions that could affect your team’s velocity.

Typed Relations

For the majority of professional web projects, TypeScript has become the programming language of choice and is, at this point, no longer even considered a superset of JavaScript, but rather the only viable solution for building sophisticated applications. That’s why, at RONIN, we thrive to build the best data platform for TypeScript developers, rather than TypeScript being an afterthought or additional augmentation. This allows us to re-imagine the entire experience of interacting with data from the ground up, with TypeScript as the primary focus of our programmatic interface. Following this objective, we are thrilled to announce that it is now possible to resolve related records without defining any custom types:

Typed Relations

For the majority of professional web projects, TypeScript has become the programming language of choice and is, at this point, no longer even considered a superset of JavaScript, but rather the only viable solution for building sophisticated applications. That’s why, at RONIN, we thrive to build the best data platform for TypeScript developers, rather than TypeScript being an afterthought or additional augmentation. This allows us to re-imagine the entire experience of interacting with data from the ground up, with TypeScript as the primary focus of our programmatic interface. Following this objective, we are thrilled to announce that it is now possible to resolve related records without defining any custom types:

For the majority of professional web projects, TypeScript has become the programming language of choice and is, at this point, no longer even considered a superset of JavaScript, but rather the only viable solution for building sophisticated applications.

That’s why, at RONIN, we thrive to build the best data platform for TypeScript developers, rather than TypeScript being an afterthought or additional augmentation. This allows us to re-imagine the entire experience of interacting with data from the ground up, with TypeScript as the primary focus of our programmatic interface.

Following this objective, we are thrilled to announce that it is now possible to resolve related records without defining any custom types:

import { get } from 'ronin';

const member = await get.member({
  with: { id: '...' },
  including: ['account']
});

// This is now fully automatically typed
console.log('Account Handle', member.account.handle);

Previously, relational fields would always have the type string, because the field value is the ID of the destination record.

With the new changes, the behavior above still applies by default, however defining fields in the including instruction will now automatically cause the type of the field to adapt and instead reflect the nested fields of the destination schema. For example, in the query above, the type of the member.account field would change from string to Account.

All it takes is installing the latest version of the ronin package:

bun install ronin@latest

As a result, it is no longer necessary to provide a custom type as a generic type argument to the query. The types are fully inferred automatically, without any manual intervention. Going forward, even more instructions will cause the types to adjust automatically.

Default Field Values

A key aspect of our mission to provide the fastest and most intuitive data platform for developers is to ensure your codebase becomes as lean and easy to understand as possible once you begin to let RONIN take care of your data-related needs. To ensure this, our programmatic interfaces (such as the TypeScript client ) are built from the ground up to expose complexity incrementally, rather than all upfront, which ensures that the flexibility of your query syntax scales proportionally to the need for more advanced functionality. No unnecessary complexity is exposed upfront. Today, we are taking this approach one step further by introducing a new Definition tab for schemas on the RONIN dashboard. On this tab, you can now swiftly configure how your schemas should react to the creation or modification of records, such that a lot of unnecessary validation, verification and formatting logic can be omitted from your application.

Default Field Values

A key aspect of our mission to provide the fastest and most intuitive data platform for developers is to ensure your codebase becomes as lean and easy to understand as possible once you begin to let RONIN take care of your data-related needs. To ensure this, our programmatic interfaces (such as the TypeScript client ) are built from the ground up to expose complexity incrementally, rather than all upfront, which ensures that the flexibility of your query syntax scales proportionally to the need for more advanced functionality. No unnecessary complexity is exposed upfront. Today, we are taking this approach one step further by introducing a new Definition tab for schemas on the RONIN dashboard. On this tab, you can now swiftly configure how your schemas should react to the creation or modification of records, such that a lot of unnecessary validation, verification and formatting logic can be omitted from your application.

June 2024

The record counts on the “Explore” page are now formatted with decimal separators, making large numbers easier to read. On the “Advanced” tab in the Account Settings, you will now find a “Language” option, which makes it possible to switch between two different variants of the English language (American and British English). When editing schemas, you can now use the Backspace or

June 2024

The record counts on the “Explore” page are now formatted with decimal separators, making large numbers easier to read. On the “Advanced” tab in the Account Settings, you will now find a “Language” option, which makes it possible to switch between two different variants of the English language (American and British English). When editing schemas, you can now use the Backspace or

Types Package

As your web app or website grows over time, you will likely find yourself also wanting to offer an increasingly better experience to your customers, which often translates into an increased amount of complexity in your application stack. There are different ways to manage this complexity, and as teams grow, one of those will be creating more Git repositories for different projects or parts of the app, rather than sticking to a single monorepo that combines all of them. Once you’ve defined your RONIN schemas for one app, you will likely want to interact with the same data from multiple Git repositories. To accomplish this, you will need to set up private packages that can share code between repositories or find a similar approach of sharing code, which, in turn, requires setting up authentication, publishing, and the like. Overall, it’s therefore a rather complex process to go through.

Types Package

As your web app or website grows over time, you will likely find yourself also wanting to offer an increasingly better experience to your customers, which often translates into an increased amount of complexity in your application stack. There are different ways to manage this complexity, and as teams grow, one of those will be creating more Git repositories for different projects or parts of the app, rather than sticking to a single monorepo that combines all of them. Once you’ve defined your RONIN schemas for one app, you will likely want to interact with the same data from multiple Git repositories. To accomplish this, you will need to set up private packages that can share code between repositories or find a similar approach of sharing code, which, in turn, requires setting up authentication, publishing, and the like. Overall, it’s therefore a rather complex process to go through.

Image Component

Thanks to our recently released Image Optimization feature, changing the size, format, quality, and aspect ratio of your image is only a matter of passing While this solution is very flexible and can be used with any software stack and language, our goal at RONIN is to help you build the fastest web application possible , and since the best web apps out there are built with TypeScript and a framework like React on the frontend, we are now launching the In addition to providing the same easy-to-use querying interface as the TypeScript client , the React client also exposes two different components that make it a lot easier for you to render the values of your fields stored in RONIN:

Image Component

Thanks to our recently released Image Optimization feature, changing the size, format, quality, and aspect ratio of your image is only a matter of passing While this solution is very flexible and can be used with any software stack and language, our goal at RONIN is to help you build the fastest web application possible , and since the best web apps out there are built with TypeScript and a framework like React on the frontend, we are now launching the In addition to providing the same easy-to-use querying interface as the TypeScript client , the React client also exposes two different components that make it a lot easier for you to render the values of your fields stored in RONIN:

Blob Storage

While most database fields of web applications usually hold rather lightweight data types (such as strings, integers, booleans, and similar), certain kinds of fields (such as the avatar of an account or the preview image of a blog post) might hold larger values and therefore require a storage that is separate from the database. Due to the “heavy” nature of large binary objects (they require more space), different considerations than those of a database are required to ensure durability, consistency, and ideal performance when accessing those objects. This often leads to setting up additional services and having to make use of different programmatic interfaces. After all, however, binary objects, just like strings, integers, and booleans, are binary representations of a value, so why should you have to use different tools, just because the value is longer? The answer is that, with RONIN, you don’t have to:

Blob Storage

While most database fields of web applications usually hold rather lightweight data types (such as strings, integers, booleans, and similar), certain kinds of fields (such as the avatar of an account or the preview image of a blog post) might hold larger values and therefore require a storage that is separate from the database. Due to the “heavy” nature of large binary objects (they require more space), different considerations than those of a database are required to ensure durability, consistency, and ideal performance when accessing those objects. This often leads to setting up additional services and having to make use of different programmatic interfaces. After all, however, binary objects, just like strings, integers, and booleans, are binary representations of a value, so why should you have to use different tools, just because the value is longer? The answer is that, with RONIN, you don’t have to:

Snapshots

As the amount of features increases in your application, it is essential to ensure every additional change is thoroughly tested automatically, in order to prevent the increasing levels of complexity from affecting your app’s reliability and thereby the end-user experience. Nevertheless, in addition to preventing any kind of regression from making its way into production, it is indispensable to also prepare for the worst case in which a regression does find its way into production and ensure that such a case does not affect the operations of your business. In other words: In the rare case that something does go south, you need to be able to recover as quickly as possible, to affecting your customers. As your database provider, it is our duty to make such a recovery affecting your data as fast and frictionless as possible, which is why you can now easily revert to a previous iteration of your data with just a single click on the “Revert” button in the new “Snapshots” section available on the Advanced tab in your Space Settings.

Snapshots

As the amount of features increases in your application, it is essential to ensure every additional change is thoroughly tested automatically, in order to prevent the increasing levels of complexity from affecting your app’s reliability and thereby the end-user experience. Nevertheless, in addition to preventing any kind of regression from making its way into production, it is indispensable to also prepare for the worst case in which a regression does find its way into production and ensure that such a case does not affect the operations of your business. In other words: In the rare case that something does go south, you need to be able to recover as quickly as possible, to affecting your customers. As your database provider, it is our duty to make such a recovery affecting your data as fast and frictionless as possible, which is why you can now easily revert to a previous iteration of your data with just a single click on the “Revert” button in the new “Snapshots” section available on the Advanced tab in your Space Settings.

August 2024

The “Definition” tab in the schema editor now provides a new “Display As” option for choosing between different UI styles for your field. For example, the "String” field type now offers “Single Line” and “Multi Line” as options, which decide the size of the text field. It is no longer necessary to press “Filter” at the top of the record list to reveal the button for changing which columns should be shown. Instead, that button is now always visible. Additionally, the UI of the associated modal was revamped to no longer require scrolling if a lot of columns are available within the modal. New filtering options named “is empty” and “is not empty” were added on the record list, for considering fields with a value of null .

August 2024

The “Definition” tab in the schema editor now provides a new “Display As” option for choosing between different UI styles for your field. For example, the "String” field type now offers “Single Line” and “Multi Line” as options, which decide the size of the text field. It is no longer necessary to press “Filter” at the top of the record list to reveal the button for changing which columns should be shown. Instead, that button is now always visible. Additionally, the UI of the associated modal was revamped to no longer require scrolling if a lot of columns are available within the modal. New filtering options named “is empty” and “is not empty” were added on the record list, for considering fields with a value of null .

Schemas in Code

When building apps with RONIN, the structure of your data is defined in the form of schemas. Those schemas contain fields, which define the format of your data. Together, they decide how the most important part of your application stack is organized: The data layer. To make adding new schemas and fields as easy as possible when developing new applications (which often involves frequently adjusting your schemas until the desired structure is achieved), RONIN has so far provided an intuitive UI on the dashboard for dragging and dropping fields into their desired structure. As larger applications continue to get built on RONIN, however, the need for more control is increasing as well. Topics such as the following become essential when defining schemas, just like they are essential for the rest of your application code:

Schemas in Code

When building apps with RONIN, the structure of your data is defined in the form of schemas. Those schemas contain fields, which define the format of your data. Together, they decide how the most important part of your application stack is organized: The data layer. To make adding new schemas and fields as easy as possible when developing new applications (which often involves frequently adjusting your schemas until the desired structure is achieved), RONIN has so far provided an intuitive UI on the dashboard for dragging and dropping fields into their desired structure. As larger applications continue to get built on RONIN, however, the need for more control is increasing as well. Topics such as the following become essential when defining schemas, just like they are essential for the rest of your application code:

July 2024

It is now possible to use the including instruction for queries when addressing a singular record, not just when addressing multiple records. Slugs of fields on the new “Definition” tab for schemas are now generated automatically, based on the name of the field. The “Copy Link” button for rows on the dashboard is now called “Highlight”, as its purpose is to allow for highlighting individual rows when sharing them. A dedicated button for copying the link of the row’s detail page will be added as well.

July 2024

It is now possible to use the including instruction for queries when addressing a singular record, not just when addressing multiple records. Slugs of fields on the new “Definition” tab for schemas are now generated automatically, based on the name of the field. The “Copy Link” button for rows on the dashboard is now called “Highlight”, as its purpose is to allow for highlighting individual rows when sharing them. A dedicated button for copying the link of the row’s detail page will be added as well.

Field Constraints

Building sophisticated and reliable web apps requires ensuring a consistent underlying data architecture so that the application never enters an unexpected state. This constraint must be a natural property of the data layer rather than being ensured by the application itself. In other words, you should never choose to increase the complexity of your codebase to handle or recover from an unexpected state caused by user input, as the application, in most cases, shouldn’t have been able to get into that state in the first place. To ensure this, RONIN is now making it easier than ever before to set the most important validation constraints for your fields with a simple click right from the dashboard: When adding a new field or editing an existing one, you can now toggle whether the value of your field should be

Field Constraints

Building sophisticated and reliable web apps requires ensuring a consistent underlying data architecture so that the application never enters an unexpected state. This constraint must be a natural property of the data layer rather than being ensured by the application itself. In other words, you should never choose to increase the complexity of your codebase to handle or recover from an unexpected state caused by user input, as the application, in most cases, shouldn’t have been able to get into that state in the first place. To ensure this, RONIN is now making it easier than ever before to set the most important validation constraints for your fields with a simple click right from the dashboard: When adding a new field or editing an existing one, you can now toggle whether the value of your field should be

Record Field Actions

When working with traditional databases, relational fields are commonly tedious to manage and interact with. In SQL, for example, obtaining the destination record of a relational column requires increasing the size of the original query significantly, by adding JOIN statements, causing an RONIN deeply embeds relations into the way in which you write code, and exposes them to you in the most natural way possible: As nested fields of your records, which are automatically resolved for you, regardless of whether you are retrieving records, updating them, or even creating them. As an example, if your app requires a “Session” schema for managing the sessions of user accounts, you could create a new session like so:

Record Field Actions

When working with traditional databases, relational fields are commonly tedious to manage and interact with. In SQL, for example, obtaining the destination record of a relational column requires increasing the size of the original query significantly, by adding JOIN statements, causing an RONIN deeply embeds relations into the way in which you write code, and exposes them to you in the most natural way possible: As nested fields of your records, which are automatically resolved for you, regardless of whether you are retrieving records, updating them, or even creating them. As an example, if your app requires a “Session” schema for managing the sessions of user accounts, you could create a new session like so:

May 2024

It is now possible to copy the value of a field by hovering the field and pressing the button that is revealed as a result. This is especially useful for the Blob field type. RONIN CLI can now be used in CI to authenticate private types packages.

May 2024

It is now possible to copy the value of a field by hovering the field and pressing the button that is revealed as a result. This is especially useful for the Blob field type. RONIN CLI can now be used in CI to authenticate private types packages.

Image Optimization

Our mission at RONIN is to ensure your application loads as fast as possible, and without any loading animations (spinners, skeletons, etc). To accomplish this, we provide the fastest data platform in the industry, focused on building modern web applications. However, ensuring the most minimal latency possible between your app and your data is only half of the story, since your app might depend on other resources that must be loaded, and if those aren’t all fast, our job isn’t done. That’s why, today, we are announcing our brand-new Image Optimization feature, which reduces the byte size of every image loaded in your app (if those images are stored in

Image Optimization

Our mission at RONIN is to ensure your application loads as fast as possible, and without any loading animations (spinners, skeletons, etc). To accomplish this, we provide the fastest data platform in the industry, focused on building modern web applications. However, ensuring the most minimal latency possible between your app and your data is only half of the story, since your app might depend on other resources that must be loaded, and if those aren’t all fast, our job isn’t done. That’s why, today, we are announcing our brand-new Image Optimization feature, which reduces the byte size of every image loaded in your app (if those images are stored in

The Hono Client

With the recent launch of the RONIN TypeScript Client , we thrived to make retrieving and inserting data into your RONIN space as intuitive as possible by mimicking the patterns of the human language (English) and avoiding any configuration overhead by default. To ensure our TypeScript Client remains as straightforward to use as possible, regardless of your application architecture, we are now introducing an additional library built on top of the aforementioned piece of software: The RONIN Hono Client . Thanks to the Hono middleware included in the client, you can initialize RONIN a single time, after which it will read the RONIN_TOKEN variable (this is where you can define an app token of your space) from your Hono context and let you easily query RONIN throughout your app.

The Hono Client

With the recent launch of the RONIN TypeScript Client , we thrived to make retrieving and inserting data into your RONIN space as intuitive as possible by mimicking the patterns of the human language (English) and avoiding any configuration overhead by default. To ensure our TypeScript Client remains as straightforward to use as possible, regardless of your application architecture, we are now introducing an additional library built on top of the aforementioned piece of software: The RONIN Hono Client . Thanks to the Hono middleware included in the client, you can initialize RONIN a single time, after which it will read the RONIN_TOKEN variable (this is where you can define an app token of your space) from your Hono context and let you easily query RONIN throughout your app.

The TypeScript Client

In preparation for the upcoming release of RONIN 2.0, which focuses on improving the developer experience and performance of the platform even further in significant ways, we are now excited to announce the official RONIN database client, written in TypeScript. Previously, querying your database from your application required setting up complicated connection URLs, “init” functions, sometimes even hostnames, usernames, passwords, and often times the database client of your choosing would not even work on your desired runtime (e.g. edge workers). The RONIN TypeScript Client, which is also available on GitHub , provides a completely zero-config experience in code, and only requires a

The TypeScript Client

In preparation for the upcoming release of RONIN 2.0, which focuses on improving the developer experience and performance of the platform even further in significant ways, we are now excited to announce the official RONIN database client, written in TypeScript. Previously, querying your database from your application required setting up complicated connection URLs, “init” functions, sometimes even hostnames, usernames, passwords, and often times the database client of your choosing would not even work on your desired runtime (e.g. edge workers). The RONIN TypeScript Client, which is also available on GitHub , provides a completely zero-config experience in code, and only requires a