Skip to main content

How to Create a Gem For JavaScript and CSS Libraries

Published: January 13, 2017 Updated: May 8, 2026 Larry Qu 3 min read

Why Package JS Libraries as a Gem

Rails projects commonly integrate JavaScript and CSS libraries like SweetAlert, Chart.js, or Bootstrap. The cleanest approach is packaging them as a Ruby gem so your application can declare a single gem line in the Gemfile instead of manually copying assets into vendor/assets. This gem-based approach ensures versioning, dependency resolution, and straightforward updates.

Building a Gem with SweetAlert

SweetAlert is a JavaScript library that replaces the browser’s default alert() dialog with customizable modal windows. The library ships with two files: sweetalert.css and sweetalert.js. These go into the gem’s vendor/assets directory so Rails’ asset pipeline can pick them up.

Creating the Gem Scaffold

Run bundle gem to generate the standard gem directory structure:

$ bundle gem sweetalert
create  sweetalert/Gemfile
     create  sweetalert/.gitignore
     create  sweetalert/lib/sweetalert.rb
     create  sweetalert/lib/sweetalert/version.rb
     create  sweetalert/sweetalert.gemspec
     create  sweetalert/Rakefile
     create  sweetalert/README.md
     create  sweetalert/bin/console
     create  sweetalert/bin/setup
     create  sweetalert/.travis.yml
     create  sweetalert/.rspec
     create  sweetalert/spec/spec_helper.rb
     create  sweetalert/spec/sweetalert_spec.rb
     create  sweetalert/LICENSE.txt
     create  sweetalert/CODE_OF_CONDUCT.md

Copy the SweetAlert assets into vendor/assets/javascripts/sweetalert.js and vendor/assets/stylesheets/sweetalert.css.

Configuring the Gemspec

Open sweetalert.gemspec and fill in the metadata: author, summary, description, and license. Add a reference to the assets directory so Bundler includes them in the packaged gem. The s.files entry should list all shipped files, and the gem version should match the library version for clarity.

Using the Gem Locally

Reference the local gem in your Rails app’s Gemfile for development:

gem 'sweetalert', path: '/data/ruby-apps/sweetalert'

Run bundle install to resolve the dependency. For production, push the gem to RubyGems.org and reference it without the path option.

Requiring Assets in the Pipeline

Add the gem’s assets to your application’s asset manifest:

// application.js
//= require sweetalert
/* application.css */
 *= require sweetalert

If you use Turbolinks, wrap SweetAlert initialization in a turbolinks:load event listener to avoid issues with page navigation.

Integrating with Rails Scaffolding

Generate a scaffold to test the gem integration:

rails g scaffold articles title:string text:text

Update articles/index.html.erb to use SweetAlert for delete confirmation:

<p id="notice"><%= notice %></p>

<h1>Articles</h1>

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Text</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @articles.each do |article| %>
      <tr>
        <td><%= article.title %></td>
        <td><%= article.text %></td>
        <td><%= link_to 'Show', article %></td>
        <td><%= link_to 'Edit', edit_article_path(article) %></td>
        <td><%= link_to 'Destroy', article,  data: { behavior: 'delete'} %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Article', new_article_path %>

Then wire up the CoffeeScript to handle the delete action with SweetAlert:

jQuery ->
  $("[data-behavior='delete']").on "click", (e) ->
    e.preventDefault()

    swal {
      title: 'Are you sure?'
      text: 'You will not be able to recover this imaginary file!'
      type: 'warning'
      showCancelButton: true
      confirmButtonColor: '#DD6B55'
      confirmButtonText: 'Yes, delete it!'
      cancelButtonText: 'No, cancel plx!'
      closeOnConfirm: false
      closeOnCancel: false
    }, (confirmed) =>
      if confirmed
        $.ajax(
          url: $(this).attr("href")
          dataType: "JSON"
          method: "DELETE"
          success: =>
            swal 'Deleted!', 'Your imaginary file has been deleted.', 'success'
            $(this).parent().parent().remove()
        )
      else
        swal 'Cancelled', 'Your imaginary file is safe :)', 'error'
      return

The key detail is setting closeOnConfirm to false so the modal stays visible during the AJAX request. The user sees immediate feedback when the delete succeeds or is cancelled.

Publishing to RubyGems

Once tested locally, build and publish the gem:

gem build sweetalert.gemspec
gem push sweetalert-1.0.0.gem

After publishing, your Gemfile entry becomes a simple gem 'sweetalert' without the path option, and any developer on the team gets the same version.

Resources

Comments

👍 Was this article helpful?