My friends: Datacore is almost ready for prime time.
The creator of the plugin has announced that the next major release will include a “stable” version that will be available in the community plugins.
What does that mean for us?
It means we can start using it!
On This Page
My friends: Datacore is almost ready for prime time.
The creator of the plugin has announced that the next major release will include a “stable” version that will be available in the community plugins.
What does that mean for us?
It means we can start using it!
On This Page
Installing Datacore
Michael Brenan, developer of both Dataview and Datacore, has announced that he will be publishing Datacore to the Community Plugins list soon. So sometime soon, you will be able to install it the same way you would any community plugin.
But until then, the best way to install Datacore is by using BRAT, which is a community plugin made for installing beta plugins. Search for and install BRAT, then go to the settings page for BRAT and click “Add beta plugin”. Paste in the below link, and BRAT will install Datacore for you.
https://github.com/blacksmithgu/datacore
Remember that this won’t be necessary for much longer. Another option is just to wait until the plugin is officially added to the Community Plugins.
Caveat: this is still beta software at the moment, so make sure to back up your vault and use at your own risk. Datacore shouldn’t corrupt any of your data, but better safe than sorry.
What is Datacore?
Datacore is a direct successor to Dataview.
Dataview is one of my favorite plugins, because it allows you to query your notes and automate many different tasks. Datacore does the same thing, but adds many more features, along with far better performance.
What’s the downside? Two things:
- Datacore is still in early development. It’s almost ready for prime time, but things are likely to change over time.
- Datacore has a more difficult syntax. Doing basic things is just a bit more involved, which makes Datacore more of a “pro” tool.
How much more involved? Well, let’s say you want to gather a list of notes tagged with “test”. In Dataview, that would look like this:
LIST
FROM #test
That is “DQL”, or the Dataview Query Language. Datacore no longer supports that language, and requires you to write everything as Datacore Queries. To do the same thing as above in Datacore, we need to write it like this:
return function View() {
const pages = dc.useQuery('@page and #test');
return <dc.List rows={pages} renderer={pages => pages.$link} />;
}
…yeah, like I said, it’s a bit more involved. The more complex syntax isn’t my favorite, but I am extremely excited about what it allows us to do. Hiding behind this syntax is extreme power and versatility.
Why Should I Use Datacore?
Dataview is still maintained and is still a great option for Obsidian. If you’re already using Dataview you might wonder: is it worth the trouble to switch to Datacore?
I think that yes, once Datacore is past its beta stage, it’s worth the effort to switch. Why? Because Datacore fixes the biggest issues that Dataview has.
Dataview is often slow, especially as your vault gets bigger and your queries get more complex. When using Dataview, you will often notice the content in your notes jumping around, which makes your notes feel unstable. It’s not a great experience, but we’ve put up with it because the benefits of Dataview are so immense.
But Datacore fixes that. The author says that Datacore is up to 100 times faster than Dataview, and it also doesn’t cause your notes to jump around like DV does. Using Datacore is a much more seamless experience, which is why I will be switching when the time comes.
Datacore also brings a new feature that Dataview lovers have wanted for years: the ability to query the contents of your notes.
The code is more complex, but with the extra complexity comes great power and performance, and hopefully once you’re done reading this article you will feel equipped to use this new language.
So let’s jump in!
Codeblocks
Like Dataview, Datacore starts with a codeblock. Anything you create with Datacore needs to exist in a special codeblock, and it looks like this:
```datacorejsx
Datacore supports [several different languages](https://blacksmithgu.github.io/datacore/code-views), but the recommended one is JSX, so for the purposes of this article we’ll stick with that\.
## Start With a Query
Like Dataview, everything in Datacore starts with a query\.
Datacore queries look like this:
dc.useQuery(“@page”);
In Datacore, we also need to *store* the value of that query somewhere, in a variable\. That looks like this:
const pages = dc.useQuery(“@page”);
“const” means we are creating a variable, and I decided to call it “pages”\.
This query returns a list of all “pages”, which is essentially a list of all the notes in your vault\. `@page` is known as a [type query](https://blacksmithgu.github.io/datacore/data/query), and type queries are generally combined with other filters, because they are too generic on their own\.
How do you add other filters? You can combine filters just like in Dataview, using `and` and `or`:
const pages = dc.useQuery(“@page and #tag”);
Tags are prefixed with the octothorpe \(\#\), and file paths are surrounded with quotes, like this:
const pages = dc.useQuery(‘@page and “projects/active”’);
The above query pulls all notes inside of the “projects/active” folder\. Handy\!
You can fine-tune these queries as much as you want using `and`, `or`, and `!not` \(e\.g\. `!#tag` matches notes that do *not* have the ‘\#tag’ tag\)
You can also use [expressions](https://blacksmithgu.github.io/datacore/expressions) to create more advanced queries\. For example, you could query for the name of a note like this:
`dc.useQuery('@page and $name = "Today";`
### Fine-Tuning Queries
Queries have many different functions available as well\. For instance, if you want to gather notes that are linked to other notes, you can use `linked()`:
// Pulls all links const pages = dc.useQuery(‘@page and linked[[Today]]’);
// Pulls notes that include a Today link const pages = dc.useQuery(‘@page and linkedto[[Today]]’);
// Pulls notes that the Today note links to const pages = dc.useQuery(‘@page and linkedfrom[[Today]]’);
Functions are super handy for specific things\. If you’re looking to query for specific metadata or specific blocks inside your note, you might want to check out the rest of the [functions in the official docs](https://blacksmithgu.github.io/datacore/data/query)\.
## Datacore Views
Once you have a query set up how you like it, next you need to display the data with a *view*\.
Views in Datacore are *React Components*, which means, as we discussed above, they require a bit more code\.
A basic React component looks like this:
return function View() { return
Hello!
; }
Let’s break that down\. `return function View() {` is the start of a *function*, and in this case it *returns a view*, which will be displayed in your note\. What does it return? Look on line two, and you will see what it returns: `<p>Hello!</p>`\.
This is not a very useful view, but it’s a start\. Everything you create in Datacore needs to be formatted in this way: a view that returns the data you want to display\.
### Datacore Lists
Now that you are familiar with views, let’s talk about lists\.
Lists are one of the most frequently used features in Dataview, and I expect they will also be popular in Datacore\. Let’s create one now\!
As usual, we will start out with a View and a query:
return function View() { const pages = dc.useQuery(“@page and #tag”); }
Then we just need one more line to turn this into a list:
return function View() { const pages = dc.useQuery(“@page and #tag”); return <dc.List rows={pages} renderer={page => page.$link} />; }
`<dc.List>` is a [React Component](https://react.dev/learn/your-first-component) supplied by Datacore that creates and formats lists for us\. In the above example, we supply two *properties*: `rows` and `renderer`\. Most of the time you will need both of these properties\.
- `rows` tells Datacore what data to use \(in this case, our `pages` variable\)
- `renderer` tells Datacore how to display that data \(in this case, we are returning the `$link` variable from inside each page\)
And that, in a nutshell, is how you create lists in Datacore\. The above example will spit out a basic linked list based on the tag you supplied\.
#### More Options for Lists
Here’s a few more cool things you can do with lists:
- Pagination\. Add `paging={true}` to add automatic pagination to lists \(more on this below\)
- Embeds\. For your rendering options, you can use `renderer={dc.embed}` to insert the *contents* of notes instead of just links\. Nice\.
- Types\. Want to add some order to your list? Use `type="ordered"` and you will get a numbered list\. You can also use `type="block"` to get rid of the list styling entirely\.
There’s a ton you can do with simple lists in Datacore, and it’s where I recommend everyone start\. Once you have a few lists under your belt, we can move on to something a bit more complex: tables\.
## Datacore Tables
Tables are more complicated than lists, because you have *two* dimensions to work with\. Instead of just rows, you have rows *and* columns\.
So as you might expect, the React Component for a table looks like this:
return <dc.Table rows={pages} columns={COLUMNS} />
It’s *kind of* the same as lists, but with the addition of the “columns” property\. But how do we configure columns?
Columns is meant to be an array, and it looks like this:
const COLUMNS = [ {id: “Name”, value: page => page.$link}, {id: “Tags”, value: page => page.$tags} ];
In this case, we are setting up two columns\. One is named “Name” and it captures the *links* to each note, and the other is called “Tags” and lists all of the tags for each note\.
So the full code for a table might look something like this:
return function View() { const pages = dc.useQuery(“@page and #tag”);
const COLUMNS = [ {id: “Name”, value: page => page.$link}, {id: “Tags”, value: page => page.$tags} ];
return <dc.Table rows={pages} columns={COLUMNS} /> }
It’s a little intimidating at first, but hopefully you see now what each piece does\.
##
One of the nice things about Datacore is that we get a lot more interactivity for free\. One of the interactive components we have access to is *pagination*\.
Lists and tables can get quite long depending on what you are looking for\. If you find your lists or tables are too long to effectively manage, try adding the paging attribute:
<dc.List rows={pages} paging={true} />
That adds this little interactive paging widget to the bottom of your list:

Paging is great\. Not only will it help you create cleaner looking views,
You can also specify the number of items you want to display per “page” by replacing `true` with an integer, e\.g\. `paging={10}`\.
## What About Sorting?
So you have your lists and your tables\. But what if you want them in a different order?
That’s where sorting comes in, my friend\. In order to sort our items, we need to make use of the `useArray` function, like this:
const pages = dc.useQuery(“@page and #tag”); const sortedPages = dc.useArray(pages, array => array.sort(page => page.$name) ); return <dc.List rows={sortedPages} renderer={page => page.$name} />;
## Other Components
There are a few other components available in Datacore at the moment \(this list will undoubtedly grow over time\)\.
### Cards
I’ve written about [cards in Dataview](https://obsidian.rocks/upgrading-obsidian-tables/) but they weren’t “officially” supported: it was a clever styling hack to make tables look like cards\.
Well, I guess Michael noticed the trend and decided to make it official for Datacore\. You can use the card component like this:
return function View() { return <dc.Card title={“Test”} content={“Testing out a card”} footer={“Hello!”} />; }
And that renders like this:

Nice\!
## Callouts
Similarly you can render [Callouts](https://obsidian.rocks/using-callouts-in-obsidian/ "Callouts") with Datacore now\. That code looks like this:
return function View() { return <dc.Callout title={“Test”} collapsible={true} open={true}>Hello!</dc.Callout>; }
And that renders like this:

## And More\!
Datacore is still growing, and new components are added every week\. If you want to see the full API, and you don’t mind reading code, [you can see it here](https://github.com/blacksmithgu/datacore/blob/master/datacore.api.md)\. Otherwise keep an eye on this article or subscribe to our newsletter, and we’ll update you as more things come out\!
## Conclusion
Datacore is a huge improvement over Dataview\. It has the potential to be everything that Dataview is, but better\.
Yes the syntax is a little more complex, but I think the benefits far outweigh the little bit of extra learning\. Datacore promises to open the door to truly reusable components for Obsidian, and we here at Obsidian Rocks are very excited about that\.