This blog uses Expressive Code for the code blocks as it’s a great tool to highlight certain lines, add insertions and deletions, file title and so much more.
But there was one thing I missed: badges with the language logo at the bottom right of the code block. Since writing plugins for Expressive Code is very straightforward (also thanks to the comprehensive guide in their docs), I decided to give it a shot.
This post will focus on the plugin, all learnings of releasing my first npm package will be discussed in another post.
What is it?
As mentioned above, the main goal of the plugin was to add language logos to the bottom right of any code block.
type User = { name: string; age: number; role: 'admin' | 'user';};The logos are the svg versions of the Simple Icons package. Notice that you have to hover the code block to see the logo with its full opacity.
package main
import ( "fmt" "net/http" "time")
type Server struct { port string timeout time.Duration handlers map[string]http.HandlerFunc}
func NewServer(port string) *Server { return &Server{ port: port, timeout: 30 * time.Second, handlers: make(map[string]http.HandlerFunc), }}
func (s *Server) Start() error { fmt.Printf("Server starting on port %s\n", s.port) return http.ListenAndServe(":"+s.port, nil)}Installation & Usage
To install, run the following command with the package manager of your choice:
npm install ec-lang-logo# pnpm install ec-lang-logo# bun install ec-lang-logo# yarn add ec-lang-logoThen, in your expressive code config, add the plugin:
expressiveCode({ plugins: [pluginLanguageLogo()],})Customization
There are two overall settings you can pass: color and excludedLangs.
expressiveCode({ plugins: [pluginLanguageLogo({ color: "mono", // accepts `mono` | `original` | any hex code excludedLangs: ["json"] // accepts any language the plugin supports })],})The original color comes from the Simple Icons package. Languages whose logos are comprised of multiple colors, like Python, will only show one color.
It’s also possible to define the color on an individual code block level with badge-color=<color> (in the meta block). I have added badge-color=original to the next block.
import Foundation
struct Task { let id: UUID let title: String var isCompleted: Bool let priority: Priority
enum Priority: String, CaseIterable { case low = "🟢" case medium = "🟡" case high = "🔴" }}
class TaskManager { private var tasks: [Task] = []
func addTask(title: String, priority: Task.Priority = .medium) { let newTask = Task(id: UUID(), title: title, isCompleted: false, priority: priority) tasks.append(newTask) }
func completeTask(id: UUID) { if let index = tasks.firstIndex(where: { $0.id == id }) { tasks[index].isCompleted = true } }}For this Rust block, I have added specified the color to be #FDBF35 (the accent color in docs.rs)
use std::collections::HashMap;
#[derive(Debug)]struct Inventory { items: HashMap<String, u32>,}
impl Inventory { fn new() -> Self { Self { items: HashMap::new(), } }
fn add_item(&mut self, name: String, quantity: u32) { *self.items.entry(name).or_insert(0) += quantity; }
fn remove_item(&mut self, name: &str, quantity: u32) -> Result<(), String> { match self.items.get_mut(name) { Some(current) if *current >= quantity => { *current -= quantity; Ok(()) } Some(_) => Err("Insufficient quantity".to_string()), None => Err("Item not found".to_string()), } }}You can also hide the icon with hide-badge.
{ "version": "v2", "userId": "d893a19f-3767-4b15-9a1b-5be0a5e2a717"}The plugin currently supports the following languages (and how to access the logos).
- JavaScript: with
jsandjavascript - TypeScript: with
tsandtypescript - Go: with
go - Rust: with
rsandrust - Zig: with
zig - Swift: with
swift - Python: with
pyandpython - Ruby: with
rbandruby - Kotlin: with
ktandkotlin - Dart: with
dart - SQL: with
sql - Bash: with
bash,shandshell - YAML: with
ymlandyaml
It also supports web-frameworks and libraries like React (with tsx and jsx), Astro, Svelte, Vue and Angular. You can find some examples for those this blog post.
Feedback & Contributions
If you encounter any issues and problems, feel free to open an issue. If there’s a language missing that you want to add to the list of supported languages, I’m happy to accept a pull request!