The Mijingo Blog

Latest news, updates, free tutorials, and more from Mijingo.

Search Git Commits with grep

by Ryan Irelan

A log of commits in Git (retrieved using git-log) can be filtered and changed to output only the commits (or types of commits) that we want to see.

Typically, you review the repository history using git-log by running:

git log

The default log is great for grabbing a quick look at what just happened in the repository. But it takes up a lot space and you can only see a handful of commits at once, unless you have a display the size of a building.

Sometimes, however, we want to only find changes that included certain keywords in the commit message. To do this we use the --grep option and pass in a term or regular expression.

git log --grep="homepage"

This will return a log with commits that only reference the word “homepage” in the commit message.

Used in conjunction with other git-log options (like --author and --since), you can very quickly narrow down the commits to exactly what you’re looking for.

Ready to learn more about Git?

Invest a small amount of time to improve how you use Git with our practical tutorial.

Get the video course

Grunt & Gulp Together (at last)

by Ryan Irelan

We’ve been learning about both Grunt and Gulp with the Mijingo JavaScript Task Runners course.

Two powerful tools, right?

As I mention in the introduction video, you don’t have to choose between the two. Use Grunt for this project and Gulp for that other project. 

Or use them together!

This short tutorial tells you how. Let’s get started.

Joining Gulp and Grunt

You make Grunt and Gulp work together by running your Grunt tasks in your gulpfile.js file. You’ll need to do the following steps in a project already set up with Gulp. Since you learned with the Mijingo course, you can just open up the Gulp project you built in the course and start there.

Install the Node package gulp-grunt by running:

npm install gulp-grunt --save-dev

If it’s not there already, move your Gruntfile.js file to the project (if you’re using the sample project from the course you’ll want to copy it over). We need it there so we can access the tasks inside of Gulp.

We have to make sure the Grunt plugins are installed so the Grunt tasks can run. No Grunt plugins, no Grunt tasks.

Individually install the Grunt plugins you need, or copy the dependencies from package.json in the Grunt project to package.json in the Gulp project.

Because we have added new dependencies, we need to install them in the project. Run

npm install

to install all project dependencies, including the Grunt plugins we just added to the package.json files.

Near the top of your Gulp file, require the gulp-grunt plugin like so:


Because we’re calling gulp, we need to do this after we define the gulp variable. This loads in the Grunt tasks defined in your Gruntfile.js file. Now we have access to them and can call them from our Gulp file.

Before we do, let’s make sure everything is working okay with our Gulp file. Let’s run gulp in the command line as a test to check.


Look good? No errors? Good, let’s continue.

Now we need to tell Gulp to run our Grunt tasks. We’ll add the Grunt task sass:dist to the default Gulp task. It will look like this:

gulp.task('default', function() {
    gulp.start('uglify', 'sass', 'grunt-sass:dist');

We added the Grunt sass:dist task to the default Gulp tasks by specifying it in the start method.

All Grunt tasks run in Gulp will use the grunt- prefix so they don’t conflict with your Gulp tasks of the same name. You don’t have to rename your Grunt tasks to make this happen, gulp-grunt will handle this prefixing automatically.

Now for the grand finale. Let’s run the Grunt task in Gulp.

Run gulp in Terminal to fire off the default Gulp task.


At the end of the output you should see something like this:

Running "sass:dist" (sass) task

Done, without errors.
[20:38:24] Finished 'grunt-sass:dist' after 1.2 s

That’s it, you did it!

Further Reading

To learn about all of the options for using the gulp-grunt Gulp plugin, review the official documentation.

Learn More About Grunt & Gulp

My video course will get you up and running on both task runners in just 90 minutes.

Get the Grunt & Gulp video course

Two Types of Git Tags

by Ryan Irelan

There are types of tags in Git: annotated and non-annotated. The names say it all: with one type we tag with an annotation on what the tag is about, while the other is tag without annotation. Both, however, are tags and mark a point of time in the life of the repository.

Annotated Tags

Annotated tags are created with a message so there’s some context–other than the name of the tag–to go with the tag.

git tag v1.2.0 -m "version 1.2.0, including new API"

In addition to the message, annotated tags also include the name of the tagger, and the date the tag was created.

If we run

git show v1.2.0

we will get something like this above the list of changes:

tag v1.2.0
Tagger: Sally Smith 
Date:   Tue Jan 27 14:06:02 2015 -0600

version 1.2.0 of the site

Non-annotated Tags

Non-annotated tags (also called “lightweight tags”) are created without a message, so the only hint as to what the tag is about is how you name it.

git tag v1.2.1

Non-annotated tags will look like a commit object, showing the changes made to the repository, but it won’t have metadata about the tag.

When do I use which tag type?

That short answer is: that’s entirely up to you.

But if you want to include the name of the tagger and a date, you should use the annotated tag. I would use annotated tags for official releases, like MySoftware v1.2.1.

git tag MySoftware-v1.2.1 -m "version 1.2.1, including new API"

This tag shows the tagger name and date, in additional to any information about the release.

For casual tagging, a lightweight or non-annotated tag should be enough.

Both tag types include the entire history log of commits, so you will always have a record of what happened leading up to the tag (remember, a tag is just a snapshot of a point in time in the life of a repository).

Ready to learn more about Git?

Get the video course

Reverting a Git Merge

by Ryan Irelan

Sometimes you get in a situation–and this is a no-judgement zone, we’ve all been there–where you merge branches and you messed up and need to undo the merge because, well, because your co-workers are kind of mad you broke the project.

Let’s say that happened. How do you revert a merge?

We have a my_feature_branch that I’ve been working in. We also have a develop branch that I merge into and deploy to my testing/staging server.

git checkout develop
git merge my_feature_branch

My merge of my_feature_branch into develop broke the site. I need to save myself from further embarrassment in front of my team, so let’s undo the merge into develop.

Because the merge is a commit that points the HEAD to a specific commit, we can undo the merge commit and roll back to the pre-merge state.

To revert the previous commit (our merge commit), we do:

git revert HEAD

We can also specify the exact merge commit that we want to revert using the same revert command but with a couple additional options.

git revert -m 1 dd8d6f587fa24327d5f5afd6fa8c3e604189c8d4>

We specify the merge using the SHA1 hash of the merge commit. The -m followed by the 1 indicates that we want to keep the parent side of the merge (the branch we are merging into).

The outcome of this revert is that Git will create a new commit that rolls back the changes from the merge.

We are saved from embarrassment! The project is working again. Now back to work to figure out why that merge broke the commit.

Ready to learn more about Git?

Get the video course

Find Out What A Command Does

by Ryan Irelan

In the command line, you’ll often find yourself wondering exactly what some command does, what the options are, and how, just maybe, you can make your use of that command even better. Here’s how to do it.

The first place I always look when needing more information about the command is the manual (or man as the cool kids might refer to it). Most well-maintained and well-documented tools will have robust manual pages for you to review.

Let’s say we need to know more about git-reset, a tool in Git that allows you to (destructively) rollback changes to your repository.

I know the command is git reset and if add the --help option to it, I’ll get the manual for git-reset.

git reset --help

In the case of git-reset, we get a healthy amount of well-written documentation and very, very helpful Examples area. The examples provided offer real-world scenarios you might face, right from the folks who are working on the Git source code.

Manual for git-reset

Another way to get help with a command is to use the man command:

man ssh

This will display the manual for the SSH command (note that ssh --help does not work).

Not every tool has as robust a manual as Git and SSH but most all do, and you can learn a lot from them. Next time you get stuck, check out the manual!

Want to learn more about the command line? Our Command Line Fundamentals course will get you started on the path to success.

Adding Your Completed Courses to LinkedIn

by Ryan Irelan

An important way to show ongoing professional improvement is by using LinkedIn’s Courses listing. Courses is a section in your LinkedIn profile where you can list the training courses you took online, in person, or at a traditional school.

Adding Mijingo courses to LinkedIn

The major driving force behind Mijingo is to provide you tools and training to continue your professional development. And, you know, it’s important to show that you’re always learning, improving, and staying on top of new techniques in your field.

Let’s make sure you can show what you’ve learned!

To add Mijingo courses you’ve completed to your LinkedIn profile, follow these steps:

  1. Log in to LinkedIn
  2. Under Profile menu, choose Edit Profile
  3. Right under your profile overview, you should see “Add a section to your profile”. Click View More and then choose Courses to add the Courses section to your profile.
  4. Click “Add course” to add a new course. For the course name, use the full name of the course on and append “from Mijingo” at the end. E.g. “Up and Running with SVG from Mijingo”. Leave the course number blank. Lastly, associate it with the position you have or had while taking the course.

Once you’ve added courses that you’ve successfully completed, save your additions and then review your profile to ensure everything looks correct.

Saving Changes with Git Stash

by Ryan Irelan

In the Basics of Git course, I was in the middle of making some changes to the homepage of our sample site when a another change request came in. I needed to quickly save–or stash away–my changes and then apply them back to the repository later, after my other work was complete.

The easiest way to do this is with git-stash, a useful git command that allows you to store the modifications you’ve made in our working directory and go back to a clean working directory.

From the Git Manual (run git stash --help to see it on your own):

Use git stash when you want to record the current state of the working directory and the index, but want to go back to a clean working directory. The command saves your local modifications away and reverts the working directory to match the HEAD commit.

Git stash isn’t a replacement for smart use of branches (we don’t want to start a new feature in a main branch and then stash it away until you’re ready to apply it) but can be a life saver if we find ourselves needing to quickly shifting gears to another task, bug report, or request.

git stash list

Fire up a current project to try out git stash.

First, let’s check if we have any existing stashes.

git stash list

The list option shows all of the existing stashes, if there are any. If you do have some they’ll be listed like this:

stash@{0}: On develop: testing out git stash
stash@{1}: WIP on master: 4fd1101 fixing layout on homepage product listing
stash@{2}: On develop: product bundle download template

Each stash is listed in a separate line, starting with the stash name that consists of the word “stash” and an index (starting with zero) in curly braces. The latest stash is the one at the top, with the index of zero (confusing, right?).

Let’s add a stash. To do that we use the stash savecommand.

stash save "updated the offline file"

The last two parts of that stash command are optional. We can just do:


instead and it will still create a stash with any changes in the working directory but without are customized message. The save option is automatically assumed if it isn’t included.

Here’s the list of stashes now:

stash@{0}: On develop: updated the offline file
stash@{1}: On develop: testing out git stash
stash@{2}: WIP on master: 4fd1101 fixing layout on homepage product listing
stash@{3}: On develop: product bundle download template

To apply a stash to the working directory, we have a couple of options. The first is:

git stash pop

which will remove the most recent stash from the list and apply it to the current working directory. It’s just reversing what you did when saving the stash (but keeping any subsequent repository changes intact).

You can also be specific and pop any stash in the list:

git stash pop stash@{1}

We should see something like this at the end of the output:

Dropped stash@{0} (38f88c1479dc8a3c63f794feed7cd276ae3c6c7e)

The other option when applying a stash is to use:

git stash apply

Just like with pop, we can choose to not specify a stash and it will use the latest. Or, we can specify one, like this:

git stash apply stash@{1}

With apply, we’ll get similar output when applying the stash, but without the message that the stash was dropped. Why? Because git stash apply applies the stash we specified but it doesn’t drop it from the list of stashes.

If we run:

git stash list

We get the full list of stashes, including the one we just applied.

stash@{0}: On develop: updated the offline file
stash@{1}: On develop: testing out git stash
stash@{2}: WIP on master: 4fd1101 fixing layout on homepage product listing
stash@{3}: On develop: product bundle download template

These are the basic commands when using stashes day-to-day. There’s more to it, and I encourage you to run:

git stash --help

to see all of the commands.

Do you need a primer on Git? Check out our course Basics of Git to get started today.

SSL/Non-SSL Site Locally with MAMP

by Ryan Irelan

In the last blog post we walked through how to set up MAMP Pro for SSL websites. This assumed that your website would be SSL all the time, for every connection. While more and more sites are becoming all SSL, many still only invoke SSL connections for critical situations, like signing in or authenticating, important form submissions, and financial transactions, like purchases.

In these SSL and non-SSL situations, a site visitor is being ushered between secure (SSL, https) and insecure (http) connections, depending on what they’re doing on the site. On Apache, this is typically set up as two different host records, one for port 80 (http) and one for port 443 (https).

When setting this up locally–as a way to emulate how our production server would work–we also need to set up two different host records on Apache.

This tutorial requires that you have a paid (or trial) copy of MAMP Pro.

Set up Non-Secure Host Record

First, let’s set up a normal MAMP host record.

(If you’re new to localhosting, I recommend our free course on localhosting, which includes how to use MAMP.)

Create the MAMP site to point at the local (public) directory of the site files you want to use. Restart the MAMP servers and then go to the site URL to confirm that it is working.

Set up Secure Host Record

This part is already covered in the previous tutorial on setting up SSL on MAMP. In summary: we’ll need to create the new host record for SSL–pointing to the same local directory as in the first step–and make sure we check “SSL” as part of the setup.

Redirecting from Non-SSL to SSL

Unless your software, CMS, or web application is set up to handle the redirect from non-SSL to SSL based on URL, you will want to do it with a redirect, using mod_rewrite rules.

Every situation will be slightly different but here’s an example of how I redirectred non-SSL connections to SSL:

RewriteCond %{HTTPS} off
RewriteCond $1 ^(account|cart/checkout|admin) [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

This starts with a mod_rewrite conditional to check if the request has HTTPS off (meaning it’s a non-secure request, over port 80), then it checks if the request has one of the URIs listed (delimited by pipes).

I can add as many URIs there to check as I wish. In this example, I’m checking for account, cart/checkout, and admin. These are all common examples of places you’d want to have SSL connections.

If the conditions evaluate to true, then the request is redirected to an https of the same URL. We’re using some variables to grab the current HTTP host and request URI.

Now when someone access, Apache will redirect to https://mijingo./dev/account automatically, never allowing /account to accessed over port 80.

Develop SSL Sites Locally with MAMP

by Ryan Irelan

Local development of SSL sites with MAMP (see our course covering MAMP and other localhosting tools) takes just a few steps to set up. If you’re using MAMP (the free version) you will have to upgrade to MAMP Pro to set up SSL locally.

Here are the steps you need to take to set up an SSL site with MAMP Pro.

Create the Host

Just like we would with a non-SSL site, we have to create a new host first. In MAMP Pro we do this by clicking the + button at the bottom left of the main window. That will create a new entry in the Hosts listing. Name it whatever you want (I’m using for my localhosting of this site).

If it’s not already, select the new host so you expose the hosting settings on the right side of the window.

I’m working under the assumption that you use the standard Apache ports for MAMP Pro (80 and 443). If you’re not, your site will not be available at the standard SSL port (443). I suggest running the same ports locally as you do in production, just so everything is the same.

Enable SSL

Next up is to enable SSL for our newly created host. With the host selected on the left, click the “SSL” tab on the right side of the MAMP main window.

Check the SSL box to enable SSL for this host. With SSL enabled we need to create certificates so we have an encrypted connection.

Fortunately, we don’t have to buy an SSL certificate for our local development (although, I suppose, we could). We can use what’s called a “self-signed certificate” instead.

A self-signed certificate means that we sign the certificate ourselves to verify its authenticity instead of going through a certificate issuing authority that verifies the certificate is indeed from us. Since we’re just using this locally–and not to serve any pages to the public–using a self-signed certificate if perfectly acceptable.

Create a Certificate file and key

There are two parts to creating an SSL certificate: a certificate file and the certificate key file. MAMP Pro makes it really straight-forward to create both.

Click the button “Create self-signed certificate…” and then fill out the form with your information. The form you input will only be used to create the certificate files on your computer and not sent anywhere.

Creating a Self-signed Certificate in MAMP Pro

After submitting the form, choose the location to save them. I typically choose the project directory or my computer user directory. MAMP Pro will create the certificate files and then add them to your config automatically.

MAMP Pro with SSL Certificates

Save your host file using the Save button.

Test the New Host

Confirm that MAMP Pro restarted the servers properly and then test the URL out in your browser. In my case I’d go to and it should load the site properly over SSL and port 443.

Now that you have that done, learn more about localhosting in our free course Reliable Localhosting.

Bash Alias to Download and Extract Latest WordPress

by Ryan Irelan

In the last blog post we covered the basics of bash aliases and how to create one. This time I want to jump back into Greg’s Command Line Fundamentals course and share a nice trick on how to automate downloading and extracting the latest version of WordPress.

This is an alias we could use just about every single day.

I have an empty directory on my computer called new-wp. I want to create an alias that will:

  1. Download the latest WordPress via wget
  2. Unarchive the download using tar
  3. Clean up by deleting the downloaded archive.

Here’s what the alias would look like:

alias get_wp="wget && tar zxvf latest.tar.gz && rm latest.tar.gz"

The first part is using the alias keyword to start defining a new alias, followed by the name of the alias. In this example we’ll call it get_wp.

Then we define the commands, starting with wget, fetching the latest.tar.gz file on the WordPress server, which always contains the latest version of the software.

We use the && operator to tell Bash to run an additional command (but only when/if the first one completes). The second command is to unarchive the file using tar.

Finally, we add another && operator to remove and bash the downloaded archive. Since we’ve already unarchived it, we no longer need it around.

Now run the command inside the new-wp directory


and see the magic happen!

If you prefer to watch instead of read, check out this excerpt of the same tutorial from Greg Aker’s Command Line Fundamentals course:

Why should you use SVG?

by Ryan Irelan

There are several reasons why SVG might be a good way to create some graphical assets on your website.


It’s what the “S” stands for. Unlike traditional images (like PNG or JPG) SVG easily scales from small to big without loss of quality or fidelity. This is because the “V” part of the name–vector–describes the series of paths, shapes, and more that are created using connect points plotted on x-y axes.

You might have noticed that SVG has come back into favor recently among web designers and web developers because of a combination of better browser support (see below), improved screen resolution (like Retina screens on iPhone, iPads, and MacBooks) and Responsive Web Design.

File Size

Another reason to use SVG is because of a file size. SVGs are typically smaller files. For example, I took a large size version of my Mijingo logo and converted it to an SVG of the same canvas size. The PNG image was 30KB and the SVG image was only 6 KB. Big savings, especially if you working on a site that requires a lean performance budget.

Modifiable via CSS and JavaScript

Since SVGs aren’t bitmapped images, they’re easily modified using both JavaScript and CSS. This makes it simple to have a base SVG file and repurpose it in multiple locations on the site with a different treatment.

SVG images aren’t perfect for everything, however. Ideally, you’d use SVGs for icons, simple line graphics, and, if possible, logos. SVGs are ideal for imagery that are used multiple times on a page (like interface icons).

Do you want to learn more about SVG? Check out our course Up and Running with SVG to get started!

Creating Bash Aliases

by Ryan Irelan

Bash aliases allow you to set a shortcut command for a longer command. For example, you could set the command cc to be a shortcut for the clear command. cc + Enter is much faster to type than clear.

Aliases are defined in the .bash_profile or .bashrc file (typically in your user home directory).

A bash alias has the following structure:

alias [alias_name]="[command_to_alias]"

A new alias always starts on a new line with the alias keyword. You define the shortcut command you want to use with the alias name, followed by an equal sign. In quote, you type the full command you want to run.

A popular example is customizing the ls command for listing directories and files. Instead of typing out

ls -lhaG

We can just shorten that to ll. Here’s the alias to do that:

alias ll="ls -lhaG"

Put that in your .bash_profile or .bashrc file and then open a new Terminal window or reload using:

source ~/.bash_profile

Now, type ll and you should see the full command run.

Here’s a video excerpt from our Command Line Fundamentals how-to video that covers the basic of bash aliases.

Want to learn the basics of navigating around the command line? Watch our Command Line Fundamentals course.

Run Gulp from Sublime Text

by Ryan Irelan

My friend and fellow teacher Mike Clark alerted me to this one after he saw it in the Sublime Text Tips email newsletter. And it is very cool.

Gulp is a Sublime Text package that makes it very, very simple to run Gulp commands and tasks right from Sublime Text.

It’s really easy to get started with it.

Running Gulp tasks inside of Sublime Text

Installing Sublime Text Gulp

The Gulp package is installed using the Package Install command in Sublime Text.

  1. Type Shift-Command-P and then type “package” until you get the “Package Control: Install Package” option.
  2. Hit Enter to have Sublime text retrieve the package index.
  3. Type “Gulp” to search for the Sublime Text Gulp package. Once you found it, press Enter to install it.

That’s it!

Running Gulp in Sublime Text

If you already have a project with a Gulpfile.js file, open it in Sublime Text. Now we use the Command Palette (Shift-Command-P) to run your Gulp tasks.

  1. Shift-Command-P
  2. Type gulp
  3. Choose “Gulp” or “Gulp (silent) which will run them in the background without output
  4. You’re done!

Running Gulp inside of Sublime Text

If you spend a lot of time in Sublime Text and need to run a special task that isn’t automated as part of gulp watch then this is a great plugin to have.

Learn more about Gulp in our JavaScript Taskrunners: Grunt and Gulp course.

Automate SVG Export on OS X

by Ryan Irelan

In a recent tutorial on exporting SVG from the command line, we installed and used SVGExport.

What’s SVGExport?

A handy command line tool you can use to convert SVG files to PNG bitmap images is svgexport. It is available as a Node.js module and a command line utility.

With svgexport, we can easily pass in an SVG file–including any resizing options for the SVG viewport–and convert it to PNG, JPG, JPEG, or PDF of varying quality.

For this tutorial, I want to build a special folder on my computer Desktop that, when I drop an SVG file in, automatically converts the SVG to PNG. It will then move the original SVG file to a different directory and move the PNG to a different directory as a way to clean things up.

To accomplish this we are going to use Automator (Mac OS X only) and a shell script. If you’re not familiar with either, it’s not a problem. We’ll walk through both of them together.


To move forward with this tutorial, please first install SVGExport via NPM.

If you’ve followed along on other courses I’ve done–like the one on JavaScript Task Runners–then installing a Node module via NPM should be old hat.

npm install svgexport -g

Also, you’ll need to be on Mac OS X so you have access to the built-in automation tool, Automator.

Setting up the Automator Folder Action

First, open Automator (available at /Applications/Automator) and create a new “Folder Action” project. There are a handful of different ways you can use Automator and a really nice option is to attach a script or series of actions to a folder.

We need to tell Automator to which folder to attach the actions. At the top, select the folder you want to use (or select “Choose…” to find any folder on your system).

I’m choosing a folder called svg2png that I created on my Desktop. The folder can be anywhere but I wanted it somewhere easily accessible.

While we’re in folder creation mode, let’s make two additional folders on our Desktop: one called source and one called processed. We’ll use these in the script to handle our input and output files.

Add Action

With the folder chosen, we now need to assign an action to it. Automator offers a generous buffet of actions to choose from–for system actions or app-specific actions–but we will keep it very simple and just use the “Run Shell Script” action.

Select the “Run Shell Script” action” from the left pane (available under Utilities) and drag it over to the right pane so it’s part of the Folder Action automation.

Make sure that /bin/bash is chosen as the option for “Shell” and “Pass Input” is set to “as arguments.” Now we’re ready to write the script!

Write the Shell Script

The shell script is fairly straight-forward but might be new to you, so I’ll explain it line-by-line. Here’s the whole script:

PATH=/usr/local/bin:/bin export PATH
for f in "$@"
  svgexport "$f" "$nf" png 100% 0.5x
  mv "$f" ~/Desktop/source/
  mv "$nf" ~/Desktop/processed/

To make things run smoothly, we want to add our system path to the top of the shell script. This allows us to call commands without the full paths and makes Node happy (which is what was used to install svgexport).

At the top of the shell script (put this in the field in the “Run Shell Script” action), we’ll add our path line.

PATH=/usr/local/bin:/bin export PATH

Now we need to tell the script to process anything that gets dropped in the folder. We do that using a for loop and we loop over an arguments array ($@):

for f in "$@"

Next up is the meat and potatoes of our Folder Action: the part of the script that processes the files and runs them through SVGExport.

  svgexport "$f" "$nf" png 100% 0.5x
  mv "$f" ~/Desktop/source/
  mv "$nf" ~/Desktop/processed/

Let’s unpack this to understand what’s going on.


First, I’m assigning the variable nf the original filename of the SVG we passed in but replacing the .svg extension with a .png extension.

svgexport "$f" "$nf" png 100% 0.5x

The next line runs the svgexport command (we don’t have to specify the full path to it because we included our system path at the top of the script). We’re using the $f variable whose value is the file of the current loop through the array as the source and the $nf variable we set earlier as the output file name. The rest of the line is standard svgexport.

mv "$f" ~/Desktop/source/
mv "$nf" ~/Desktop/processed/

Finally, we move the source file ($f) to the source folder on our Desktop and the move the processed PNG file ($nf) to the processed folder on our Desktop.

Add done at the end to close the loop and we’re done!

Automator window for exporting SVG as PNG

Saving and Testing

Save the Folder Action automation in Automator. Now it’s time to test it out. Find an SVG file and drag and drop it (or copy and paste it) into the svg2png folder. You should see a small, spinning gear appear in your menu bar. Once the automation is complete the gear will disappear.

We check our processed folder to see if the PNG file is there. Success!

This script could be enhanced and made better. For example, I’m doing any error checking here to accounting for missing files, duplicate files, etc.


If we run into problems, we can test the automation right inside of Automator by explicitly passing a file to the “Run Shell Script” action. We use the “Get Specified Finder Items” action (dragging it above the “Run Shell Script” action), choosing an SVG file to test with, and then running the automation manually.

Using Get Specified Finder Items in Automator to test

Some common problems we might see:

  • Path problems (script can’t find command) if the system path is missing from the top of the script
  • Missing directories that are called in the script (processed, source)
  • SVGExport isn’t installed
  • Not setting “Pass input” as “arguments” for the Shell Script action

For more information about how to get started with SVG, check out our comprehensive course Up and Running with SVG.

Cutting Assets with Slicy

by Ryan Irelan

Preparing assets properly for web or mobile apps can be a pain. You have to create multiple sizes and versions and you have tediously go through the PSD to export what you need.

In this excerpt from the Fundamentals of iPhone App Design course, Funsize designer Rick Messer shows how to use Slicy to quickly export assets for the NearMe iPhone app he builds in the course.

To get start using Slicy here’s what you need to do:

  1. Download Slicy (and then grab a license) and install it (Mac OS X only)
  2. In your PSD, properly name your layers per the instructions Rick gave in the video (the layer name should be the name of the image you want to export). If you’re designing at 2x then Slicy will automatically create the 1x images for you (pretty cool!).
  3. Set up AutoRepeat in Slicy so it will automatically export new images when you edit the layers.

Want to learn more about iPhone app design? Watch our Fundamentals of iPhone App Design Course.

Why You Shouldn’t Use Git Fast Forward

by Ryan Irelan

I’ve been using the Git Flow branching model for a while (but at times not very strict). Maybe because it’s buried in the original article but I didn’t realize until now that there’s a very good reason to not allow fast-forwards when merging branches.

The –no-ff flag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a feature branch and groups together all commits that together added the feature.

If you do git merge without the --no-ff option then

it is impossible to see from the Git history which of the commit objects together have implemented a feature—you would have to manually read all the log messages. Reverting a whole feature (i.e. a group of commits), is a true headache in the latter situation, whereas it is easily done if the –no-ff flag was used.

I’ve been there. Using --no-ff would’ve saved me a lot of time.

If you aren’t already familiar with it, Vincent’s A successful Git branching model is a canonical article on using Git.

Adding to Your System Path

by Ryan Irelan

The System Path is a special environment variable in your command line session that references the full file system path to the location of binaries and executables (command line applications).

What follows assumes you’re using Bash and may be OS X biased.

It is typically located in your user home directory inside of a hidden file called .bash_profile or .bash_rc (here’s a good comparison of the two files. Most of the time you’ll use .bash_profile.

Basically, the System Path lets you cheat at the command line by only typing the command name and not the exact location of it.

Knowing about the System Path is important because as you get more experience working on the command line you may have to install software that will require you to update your system path in order to run the software from the command line without specifying the full path.

As an example, I run the git command dozens of time per day. But I just run git and nothing else. My system knows where to find the location of the Git binary (the Git application itself) because the location is listed in my System Path.

The actual location of git is /usr/bin/. If I ran /usr/bin/git it’s the same thing as if I ran only git.

But my System Path doesn’t know explicitly about Git. It has a set of paths (full locations to directories) that it checks each time I run a command. If there are 3 paths set, my Terminal session will check each one until it finds the location of Git.

To add to, edit, or just view your System Path, you’ll need to access the .bash_profile. I like to do this using vim.

It’s okay, I know. Sounds scary. But I’ll walk you through it. We start by opening up the .bash_profile in Vim.

vim ~/.bash_profile

The .bash_profile file is located in the user home directory. We use the tilde as shortcut for that. Once that’s open you should see something like this near the top:

export PATH=/usr/local/bin:~/bin:$PATH

This your System Path. It has two paths defined to check when we run a command. Let’s add another path to it.

In order to edit the file in Vim, we’ll need to go into insert mode. Press the “i” key. Then use your arrow keys to navigate to the end of the export statement. Type in the path you need to add.

Mine is going to look like this:

export PATH=/usr/local/bin:~/bin:/Applications/$PATH

We added a colon and then the path to the Inkscape binary for the command line tool (see more about using that). The path is an absolute, full path right to the directory that contains the binary.

After you’re done editing, hit the Escape key (or control-c) and then type :wq for write and quit. You should be dropped back into the command line prompt.

Before the current terminal session knows about the changes we’ve made, we need to reload our .bash_profile. We can do that by opening a new Terminal window or running:

source ~/.bash_profile

Now let’s test out the change: inkscape (whatever command you need to run will probably be different).

Ready to learn more about the command line? Our Command Line Fundamentals course will get you up and running in no time.

Exporting SVG from the Command Line with Inkscape

by Ryan Irelan

I’ll go ahead and say this up front: using Inkscape isn’t the most desirable method. Not because Inkscape is an unreliable tool but because it requires that the Inkscape app and X11 app are both installed. Inkscape is a cross-platform application so it runs on X-Windows and provides a non-native app experience.

But if you are already using Inkscape to draw your SVGs, then you would be best served scripting the command line tool of the tool that you already have open.

There are two ways to interact with Inkscape from the command line:

  1. Using the Inkscape interactive shell mode
  2. Running the inkscape command line tool

The interactive shell mode is enabled by running inkscape --shell.

If you want to do scripting (like bash scripting) to batch process images, the command line tool is your best option.

On OS X, the command line utility is located inside of the Inkscape application package, which you can find at: /Applications/ If you want to call this like I do below, you’ll want to add the location to your system path.

Using the same file we used in the tutorial on using svgexport, here’s how to convert an SVG to PNG with the Inkscape command line utility:

inkscape -z css3-fundamentals.svg -e css3-fundamentals.png

The first part calls the inkscape utility. The -z option is supposed to suppress the Inkscape GUI. This sort of worked for me, but still required X11 on OS X to launch.

The -e option tells Inkscape that we want to covert to a PNG image. And, then we pass in the name and extension of the destination image.

This SVG to PNG conversion method is very reliable if you already have Inkscape installed. If you don’t run Inkscape already then you might want to check out my tutorial on exporting SVG with SVGExport.

Learn more about SVG with our comprehensive course: Up and Running with SVG

Exporting SVG from the Command Line with SVGExport

by Ryan Irelan

A handy command line tool you can use to convert SVG files to PNG bitmap images is svgexport. It is available as a Node.js module and a command line utility.

With svgexport, we can easily pass in an SVG file–including any resizing options for the SVG viewport–and convert it to PNG, JPG, JPEG, or PDF of varying quality.

Installing svgexport

If you’ve followed along on other courses I’ve done–like the one on JavaScript Task Runners–then installing a Node module via NPM should be old hat.

npm install svgexport -g

That will install the utility globally so you have access to it anywhere.

Okay, let’s get to covertin’.

Converting One SVG to PNG

I have some new artwork in SVG format for Mijingo courses that I want to use on the site. But before I can an image I need to convert the SVG to PNG to use as fallback image (and in other instances, like email campaigns).

In this example we will convert one SVG image to a PNG. We’ll pass an explicit file and specify an output file name.

svgexport css3-fundamentals.svg css-fundamentals.png png 100% 500:648 250:324

There are a few parts to this command, let’s break it down.

svgexport [input file] [output file] [format] [quality] [input viewbox] [output size]

The first part, svgexport, is, of course, the command we are running. After that we pass it the file we want to covert (our SVG file). We need to specify the quality, too. The range is 1-100% and we’ll make it full quality at 100%.

The last two options are for sizing. Sizing options are set with the width:height pattern.

First, we specify the viewbox of the input file. According to the svgexport package instructions, the viewbox will be inferred from the source file unless we specify one. I like to be explicit in my commands, so as to leave nothing for chance, so I’m going to set the viewbox option.

Finally, we set the output size of the image. For my needs right now I need the output size to be exactly half.

Here’s the command we’ll run in a directory that contains the css3-fundamentals.svg file:

svgexport css3-fundamentals.svg css-fundamentals.png png 100% 500:648 250:324

Let’s run that command. You should see an output similar to this:

/Users/ryan/Desktop/covers/css3-fundamentals.svg /Users/ryan/Desktop/covers/css3-fundamentals.png png 100% 0.5x 0:0:500:648 250:324

Another option is to use a scale option instead of specifying the exact height width of the final image. I know this SVG is 500x648. I want to make it half that size. Instead of specifying 500x648, I could also use 0.5x as the scale. You can see this in the output from our first command.

svgexport css3-fundamentals.svg css-fundamentals.png png 100% 500:648 0.5x

The output (both the file and what is returned on the command line) is the same as the first command. My preference is to always be explicit because if I try to pass in a larger SVG than 500x648 and use the 0.5x scale option than my final PNG will not be what I need.

However, the scale option can be handy if you need to resize multiple images of different sizes. In that case we would leave out the viewbox option and let svgexport use whatever is specified in the SVG file code.

svgexport css3-fundamentals.svg css-fundamentals.png png 100% 0.5x

This is particularly handy if you have a series of images of different sizes that you want to just scale half size.

Converting to Other Formats

svgexport also lets you export to other formats like JPG, JPEG, and PDF. It’s the same command as before but just use a different format value (pdf for example). If you leave out the file format, svgexport will default to PNG files. I like to be explicit in my commands so it’s clear what I’m doing (especially if this is part of script that I’m leaving behind for someone else). Therefore, I always specify the image format even if it’s the one that is the default. Defaults are good but not if they create confusion.

The Options Available

To get all of the options available for the svgexport command, I like to review the documentation that comes with it. You can get that by running:


On my installation of svgexport there’s no documentation available using the man command, but just typing svgexport on its own will output the command usage.

In an upcoming tutorial I’ll cover how to script this so we can batch process SVGs in a directory, converting them all to PNG files.

If you use Inkscape, check out the tutorial on exporting SVGs with the Inkscape command line utility.

Learn more about SVG with our comprehensive course: Up and Running with SVG

SVGO Exporter for Adobe Illustrator

by Ryan Irelan

A new project from David Deraedt called SVG NOW that is an alternative SVG exporter for Adobe Illustrator. This is great news because the code that comes out of Illustrator isn’t as optimized as it could be.

The exporter uses SVGO, so you’ll presumably get (it is in beta and still under development) all of the goodness that is SVGO right inside of Illustrator. Including the SVGO plugins that are available and enabled by default.

From the README file:

It is built on top of Illustrator’s SVG exporter, controls some of its parameters and default values, and runs a customized version of SVGO (node module) with an HTML GUI built on top of it to control its plugins.

Follow the project on Github

Previous Page   Next Page

What are our customers saying?

"Just purchased your Flexible Twig course. Love it!"
Tyler Morrison
"Been enjoying @mijingo 's Learning Craft video tutorials. Feeling like I've got a good basic understanding of #craftcms Very impressive"
Laura Montgomery
"I bought your Craft Starter Pack a year and a half ago. Worth every dollar. In fact, I would've paid twice as much for it, because you saved me so much time."
Timothy Ingram
"Ben's knowledge of Craft combined with his relaxed and informal teaching style makes for a great learning experience."
Steve Abraham
"Ben puts a lot of thought into his teaching approach and has the ability to explain complex concepts in a way that just make sense"
Gareth Redfern
"Ben is great at taking a complex subject and breaking it down in a way that you can wrap your mind around. I thought that plugin development was something I would never understand, and happily Ben proved me wrong!"
Jonathan Melville
"I really appreciate all the videos and writing you have done. Your work has given me a jump start on my front end development business."
Shan Ricciardi

Perfect for Small Teams & Companies

Mijingo's courses are perfect as the training curriculum for both small teams and entire companies.

Our courses are offered in Team Packs (up to 5 people) and Company Packs (up to 25 people), so you can make one simple, fast purchase to train your entire staff.

Prices are listed with each course. Need more than 25 or something custom?

Send Your Requirements
Team Pack2-5 People
Company Pack6-25 People
Custom Pack25+ People