Getting started with Solana can be quite the chore without a guide. In this article, I’ll make sure we have everything ready in our local machine to get started with Solana programs using the Anchor framework.
Since there is quite a lot to go through, I'll make sure to get to the point quickly so you can re-read this article as an actionable checklist in the future. That being said, we will spend a bit of time digging through how Anchor works to better understand the "Build, Deploy, Test" cycle we will use throughout this series.
If you're a Windows user, I'm afraid this guide is more tailored for Linux and Mac users. Fortunately, Buildspace has got a nice guide for installing Solana on a Windows machine so hopefully, you can still follow along after that.
I’d also like to add that the Solana ecosystem moves relatively quickly and, therefore, some of these steps might end up changing or — fingers crossed — being simplified in the future. If that’s the case, please reach out to me and I’ll make sure to update the article accordingly.
Finally, here's a table of content in case you're re-reading this and looking for a particular section.
Why? Rust is the language Solana uses to build programs.
Installing Rust is as simple as running this.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
When installed, it will add the following PATH — or similar — to your shell configurations which is good to know if you want to move that to your dotfiles or something.
You can check that rust is properly installed by running the following commands.
rustup --version rustc --version cargo --version
Similarly, you can install Solana by running the following installer script.
sh -c "$(curl -sSfL https://release.solana.com/v1.8.5/install)"
Note that newer versions have been released since then so feel free to use them but this is the Solana version I used for this tutorial.
Installing Solana will also add a new PATH to your shell configurations. Alternatively, depending on your system, it might ask you to manually update your PATH by providing you with a line to copy/paste.
You can check that Solana is properly installed by running the following commands.
# Check the Solana binary is available. solana --version # Check you can run a local validator (Run Ctrl+C to exit). # We’ll see what this does in this article. # Note this creates a "test-ledger" folder in your current directory. solana-test-validator
Install Solana on Apple M1
Unfortunately, at the time of writing, the Solana installer script above will not work on Apple M1 computers.
The installation will be successful and you’ll be able to call
solana commands but other Solana binaries such as
solana-test-validator will throw various errors since it’s expecting dependencies to be located elsewhere. If you’ve already installed it that way, no worries, simply run
rm -rf ~/.local/share/solana to uninstall Solana.
I’ll be sure to update this article if/when this will work out-of-the-box for M1 computers.
In the meantime, we’ve got a little workaround to go through. We need to clone the Solana repository and compile the binary from the source code. Don’t worry, the installation process is still super simple, it just takes a bit longer due to the compilation time. Here are the steps.
# Go to your dev folder (for me it’s “~/Code”). cd ~/Code # Clone the Solana repository and cd into it. git clone https://github.com/solana-labs/solana.git cd solana # Checkout the latest stable branch. git checkout v1.8.2 # Run the installation script (it takes a while). ./scripts/cargo-install-all.sh .
At the end of the script, it should provide you with a line to copy/paste in your shell configuration to update your PATH accordingly. Open your
~/.zshrc file — or
~/.profile or whatever file you use — and paste that line in there. In my case that was:
To check that Solana is properly installed, you may run the following commands.
# Check the solana binary is available. solana --version # Check you can run a local validator (Run Ctrl+C to exit). # Notice the special flag. We’ll explain that in a minute. # Note this creates a "test-ledger" folder in your current directory. solana-test-validator --no-bpf-jit
If you're having more troubles along the way, Note that Buildspace also has a detailed guide on how to install Solana for Apple M1 computer that they keep up-to-date.
Use Solana locally
Why? Solana defaults to using the “mainnet” network. For now, we want to develop our programs locally before we deploy them for real.
solana config set --url localhost
After running this, you should see all your configs pointing to localhost URLs which is exactly what we want.
Generate your local key pair
Why? We need a public and private key to identify ourselves when using the Solana binaries locally.
First, you might want to check if you've already got a local key pair by running the following command.
If you get an error, that means you don't have one yet and so let's create a new one.
Simply run the following command and follow the steps. Personally, I don't enter a paraphrase since the generated key pair will only be used locally.
At the end of the process, you will be given a long recovery phrase that can be used to recover both your public and private key. Even though it's only used locally, I still store that recovery phrase on my password manager just in case.
Note that you can recover any key pair by running
solana-keygen recover and providing the recovery phrase in the process.
Why? Anchor is a Solana framework that significantly improved the developer experience when creating programs.
You can install Anchor in your local machine by running the following command.
cargo install --git https://github.com/project-serum/anchor anchor-cli --locked
Note that you can also install Anchor using
npm globally but since I use multiple versions of
nvm I'm not a big fan of
npm global dependencies.
You may run the following command to check Anchor CLI is installed properly.
Why? By default, Anchor relies on
If you don't have it installed already, you can do so by running one of the following commands:
# Using npm global dependencies. npm install -g yarn # Using homebrew on Mac. brew install yarn # Using apt on Linux apt install yarn
Create a new Anchor project
Now that we have Anchor installed, we can run
anchor init to start a new project!
# Go to your dev folder (for me it’s “~/Code”). cd ~/Code # Create a new Anchor project. anchor init solana-twitter # Cd into the newly created project. cd solana-twitter
Inside our new project, Anchor prepared a bunch of things for us:
programsfolder for all our Solana programs. It already comes with a very simple program we can build upon so we don't have to do all the scaffolding.
Anchor.tomlconfiguration file helping us configure our program ID, Solana clusters, test command, etc.
- An empty
Now that we have our project scaffolded, let's see how we can build, deploy and test the default program generated by Anchor. That way, we'll understand more about the development cycle of building a Solana program.
Build and deploy
Anchor has two very useful commands that will delegate to the Rust compiler and Solana CLI tools to build and deploy your programs for you.
# Compiles your program. anchor build # Deploys your compiled program. anchor deploy
Whilst these commands are not necessary to compile and deploy, they certainly make the developer experience a lot more enjoyable by abstracting all of the more complex commands we would otherwise need to run.
That being said, let's have a quick look at what happens when we run these commands.
First, our code is compiled and we will be shown any warnings or errors that occur at compile time. The Rust compiler is pretty powerful so if we did something wrong in our code, it most likely won't let use compile it.
Let's run this command on our brand new project.
As you can see our program compiled but you should see the following warning:
unused variable: 'ctx'. That's fair because the auto-generated program is so simple that it doesn't actually do anything with that
ctx variable and, therefore, the compiler warns us it's not being used. We can safely ignore that warning for now.
Additionally, once our code was compiled, the
target folder was updated accordingly. You don't need to fully understand what's happening inside that folder but it basically keeps track of any built releases and deployment of our program. Note that this folder is relative to your local machine and will not be committed to your
anchor build also generated an IDL file. IDL stands for "Interface Description Language" and it is quite simply a JSON file that contains all the specifications of our Solana program. It contains information about its instructions, the parameters required by these instructions, the accounts generated by the program, etc.
anchor deploy will take our latest build and deploy it on the cluster.
Note that the first time you build a program, it will also generate a public and private key for it — which will be stored in the
target directory. The public key generated will become the unique identifier of your program — a.k.a the program ID.
Since we've set up our cluster to be
localhost earlier, we currently have no network to deploy to. That means, if you try to run
anchor deploy right now, you'll get an error saying
error sending request for url (http://localhost:8899/).
To fix that, we need to run a local ledger.
Run a local ledger
A local ledger is basically a simulation of a Solana cluster inside your local machine. When building locally, we don't actually want to send anything to the Solana blockchain so this is exactly what we want.
Fortunately for us, running a local ledger is as simple as running the following command.
This command will keep a session open in your terminal until you exit it by running
Ctrl+C. Whilst the session is open, you now have a local ledger to deploy to! 🎉
That means you can now run
anchor deploy and it successfully deploy to your local ledger.
Note that all the data sent to your local ledger is stored in a
test-ledger folder created in the current directory.
So let's make sure we don't commit that entire folder to our
git repository by updating our
.gitignore file like so.
.anchor .DS_Store target **/*.rs.bk node_modules + test-ledger
Also note that exiting your local ledger (by running
Ctrl+C) will not destroy any data you've sent to the cluster. However, removing that
test-ledger folder will. You can achieve the same result by adding the
# Runs a new empty local ledger. solana-test-validator --reset
Run a local ledger on Apple M1
There's one little quirk here for Apple M1 users. By default, the local ledger uses something called "BPF just-in-time" which is not compatible with Apple M1 computers. Therefore, we need to add the
--no-bpf-jit flag to make it work.
Note that this issue should be resolved soon as Solana has already worked on a fix that will automatically detect if a machine supports BPF just-in-time.
Update your program ID
Now that we've run
anchor build and
anchor deploy for the first time, we need to update our program ID.
As we've mentioned above, a new key pair for our program is generated on the very first deployment. Before that, we simply don't know what the public address of our program will be.
Your program ID should be displayed when running
anchor deploy but you may also access it by using the following Solana command.
solana address -k target/deploy/solana_twitter-keypair.json # Outputs something like: 2EKFZUwMrNdo8YLRHn3CyZa98zp6WH7Zpg16qYGU7htD
Depending on how you named your anchor project, this file might be called something else so you may have to look at the
target/deploy folder to find the right file.
Okay now that we know our program ID, let's update it.
When we created our new project using
anchor init, Anchor used a random placeholder in two places as our program ID that we can now replace.
First, in our
Anchor.toml configuration file.
[programs.localnet] solana_twitter = "2EKFZUwMrNdo8YLRHn3CyZa98zp6WH7Zpg16qYGU7htD"
Then, in the
lib.rs file of our Solana program. In my case, that's
use anchor_lang::prelude::*; use anchor_lang::solana_program::system_program; declare_id!("2EKFZUwMrNdo8YLRHn3CyZa98zp6WH7Zpg16qYGU7htD");
Finally, we need to build and deploy one more time to make sure our program is compiled with the right identifier.
anchor build anchor deploy
Before we wrap up this article, I’d like to make sure we can run the generated tests on our program.
If you look inside your
Anchor.toml file, you'll notice a
scripts section containing a
[scripts] test = "yarn ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"
This is already configured for us so that it'll run all the tests inside our
tests folder using Mocha.
To run that script, run the following command.
anchor run test
If you have a local ledger running — via
solana-test-validator — and you've built and deployed your project properly — via
anchor build and
anchor deploy — then you should see the test passing!
Note that you can add any custom script to your
Anchor.toml configuration file and use
anchor run to execute it. Here's a quick example.
[scripts] test = "..." my-custom-script = "echo 'Hello world!'"
anchor run my-custom-script # Outputs: Hello world!
Alright, we now know the full development cycle. First, you need a local ledger, then you can build, deploy and test. Here's a quick recap:
# Start the local ledger. solana-test-validator # Then, on a separate terminal session. anchor build anchor deploy anchor run test
Well, it turns out anchor has a special command that takes care of that full cycle for us. It's called:
⛔️ Not to confuse with
anchor run test that only runs the test script inside your
So what does
anchor test actually do?
- First, it starts a local ledger that will be automatically terminated at the end of the command. That means you cannot run
anchor testif you already have a local ledger running. Make sure to terminate any local ledger before running
anchor test, this is a common gotcha. Also, note that it uses the
--resetflag to make sure our tests always start with the same empty data.
- Now, Anchor is ready to build, deploy and run the tests.
anchor build anchor deploy anchor run test
anchor test command is really powerful when developing your Solana programs locally. It abstracts away all the faff and lets you focus on your program.
Remember though that running
anchor test immediately after generating a new project — via
anchor init — will not work because you'll first need to update your program ID after the first deployment.
Therefore I suggest, you build and deploy manually the very first time and once you've updated your program ID, you can start using
If you end up working on other Anchor projects, you might come across the
anchor localnet command. This command is very similar to
anchor test except that it does not run any test and does not terminate the local ledger at the end.
Thus, it is basically the equivalent to:
solana-test-validator --reset anchor build anchor deploy # The local ledger will stay active after deployment.
This command is typically used to quickly spin up your program when working on your frontend client.
Anchor test and localnet on Apple M1
If you're an M1 user, then I'm afraid the
anchor test and
anchor localnet commands will not work for you just yet.
This is because both of them are calling
solana-test-validator without the
--no-bpf-jit flag which is necessary for a local ledger to work on an M1 computer. That being said, when this
--no-bpf-jit flag issue will be fixed, M1 users should be able to fully enjoy these two anchor commands.
In the meantime, instead of
anchor test, you'll need to run:
# Start and reset your local ledger. solana-test-validator --reset --no-bpf-jit # Then, on a different terminal session # Run anchor test without the local ledger. anchor test --skip-local-validator
And instead of
anchor localnet, you'll need to run:
# Start and reset your local ledger. solana-test-validator --reset --no-bpf-jit # Then, on a different terminal session # Build and deploy your program. anchor build anchor deploy
Phew, we got there in the end! Congratulations on setting up your local machine with Solana and Anchor. On top of that, we now have a fully scaffolded project we can use to build our Twitter in Solana project.
I do hope you didn't encounter too many issues along the way. I know setting up things on your machine can be a real nightmare especially when the technology is moving quickly. If you have any issues feel free to add a comment to this article or better yet, create an issue on the GitHub repository below so anyone can jump in and help you across all episodes.
If you want to see the code we generated during this episode, here's a link to the
episode-2 branch of this series' repository.
Now that, we're all set up and we understand our development cycle, let's start building things! 🔥