SilkIcons - A stupidly easy icon module!

SilkIcons - A stupidly easy icon module! :artist_palette::sparkles:


(All icons avaliable in SilkIcons rendered together using the module)


Download Link: SilkIcon.rbxm (21.2 KB)

Hello!

This is my first module post on here, so I hope you take the time to read it!

Picture this:
You’re working on a Roblox game. You need icons. Don’t have any? Simple! Just plug in this module into your game, and just like that, you have high quality, crisp, and clean icons you can use in your game!


Features

  • Create icons by name with one line of code
  • Automatically sets image size, offset, and pixelated resampling
  • Switch icons dynamically at runtime
  • Comes with a full list of supported icon names under the module as README

How to Use

1. Require the module

local SilkIcon = require(path_to_SilkIconModule)

2. Create a new icon image

local icon = SilkIcon.Get("add")
icon.Parent = someGuiParent

3. Change the icon

SilkIcon.ApplyTo(icon, "delete")

Icon List

You can find the full list of available icons inside the module in the "README" script (or in the index file). This list contains all the icon names you can use with SilkIcon.new() or SetIcon() methods.


Example

repeat task.wait() until game:IsLoaded()

local IconService = require(game:GetService("ReplicatedStorage").Modules.SilkIcon)
local iconIndex = require(game:GetService("ReplicatedStorage").Modules.SilkIcon.index)

local screenGui = script.Parent
local iconsPerRow = 32
local padding = 0

local xPos, yPos, maxHeightInRow, count = 0, 0, 0, 0

for iconName, iconData in pairs(iconIndex.icons) do
	local icon = IconService.Get(iconName)
	icon.Position = UDim2.new(0, xPos, 0, yPos)
	icon.AnchorPoint = Vector2.new(0, 0)
	icon.Parent = screenGui

	local width = iconData.imagerectsize[1]
	local height = iconData.imagerectsize[2]

	xPos += width + padding
	maxHeightInRow = math.max(maxHeightInRow, height)
	count += 1

	if count % iconsPerRow == 0 then
		xPos = 0
		yPos += maxHeightInRow + padding
		maxHeightInRow = 0
	end
end

Installation and Usage

  • Drop the module into your project
  • Require it
  • Use the icon names from the README to create icons

If you want a good and clean way to add icons to your UI, give it a try! Feel free to ask questions or suggest improvements.

Happy developing!


Icons created by FamFamFam (Mark James) — Thank you for the icons!

10 Likes

Here’s a functional version of this module that doesn’t use OOP because it is massively unnecessary in this case (replace the main module code with this):

--[[
	A simple, functional module for creating and managing icon ImageLabels from a spritesheet.
	
	This version includes optimizations to prevent redundant property setting and to
	improve code readability by caching values.
]]
local IconService = {}

-- Load the icon data from the index file. This is done only once when the module is required.
local iconIndex = require(script.index)

-- A constant for the attribute name to ensure consistency.
local ICON_ATTRIBUTE_NAME = "IconName"

-- Type definition for the data expected for a single icon in the index.
type IconData = {
	imagerectoffset: {number},
	imagerectsize: {number},
}

--[[
	Creates and returns a new ImageLabel configured with the specified icon.
	
	@param iconName The name of the icon to create.
	@return A new ImageLabel instance with the icon applied.
	@error If the icon does not exist in the index.
]]
function IconService.Get(iconName: string): ImageLabel
	local iconData: IconData = iconIndex.icons[iconName]
	if not iconData then
		error("IconService: Icon '" .. iconName .. "' does not exist.", 2)
	end

	local imageLabel = Instance.new("ImageLabel")
	
	-- Configure the ImageLabel with shared properties
	imageLabel.Image = iconIndex.image
	imageLabel.ResampleMode = Enum.ResamplerMode.Pixelated
	imageLabel.BackgroundTransparency = 1
	
	-- Apply the specific icon's properties using the ApplyTo function to avoid code duplication.
	-- The redundancy check inside ApplyTo is not strictly needed here since it's a new instance,
	-- but this keeps the logic centralized and clean.
	IconService.ApplyTo(imageLabel, iconName)
	
	return imageLabel
end

--[[
	Applies an icon's properties to an existing ImageLabel.
	This is optimized to do nothing if the requested icon is already applied.
	
	@param targetLabel The ImageLabel instance to modify.
	@param iconName The name of the icon to apply.
	@error If the icon does not exist in the index.
]]
function IconService.ApplyTo(targetLabel: ImageLabel, iconName: string)
	-- Optimization: Check the instance's attribute to see if the icon is already set.
	-- If it is, we can skip all the work.
	if targetLabel:GetAttribute(ICON_ATTRIBUTE_NAME) == iconName then
		return
	end

	local iconData: IconData = iconIndex.icons[iconName]
	if not iconData then
		error("IconService: Icon '" .. iconName .. "' does not exist.", 2)
	end
	
	-- Optimization: Cache the table values in local variables.
	-- This avoids repeated lookups (e.g., `iconData.imagerectsize`) and is slightly faster.
	local rectOffset = iconData.imagerectoffset
	local rectSize = iconData.imagerectsize

	-- Note: We only update properties that are specific to the icon.
	-- Shared properties like Image and ResampleMode are assumed to be set on creation.
	targetLabel.Size = UDim2.fromOffset(rectSize[1], rectSize[2])
	targetLabel.ImageRectOffset = Vector2.new(rectOffset[1], rectOffset[2])
	targetLabel.ImageRectSize = Vector2.new(rectSize[1], rectSize[2])
	
	-- Store the current icon name in an attribute on the instance for the next check.
	targetLabel:SetAttribute(ICON_ATTRIBUTE_NAME, iconName)
end


return IconService

Old usage:

local iconObject = SilkIcon.new("keyboard")
local keyboardIcon = iconObject:GetInstance()
keyboardIcon.Parent = someFrame

New usage:

local keyboardIcon = IconService.Get("keyboard")
keyboardIcon.Parent = someFrame

(disclaimer: I used gemini 2.5 pro to do this)

6 Likes

thanks voidage you’re the GOAT :goat:!

3 Likes

Hi, I noticed some issues with your “functional version” that I think could have been improved on.

  1. For the Get() and ApplyTo() methods, you could have put the imagerectsize and imagerectoffset values into variables, as that would have saved redundant calls.
  2. You could have stored the current icon name, so if the player tries to set it again to the same icon, it could catch that and prevent unnecessary changes, optimizing it.

I see that the OOP approach I took was unnecessary, however your case could be optimized aswell.

2 Likes

In all seriousness though, do you mind if I use this code to update the module?

1 Like

I don’t mind at all. And here is an updated version of the module to take those issues into account:

--[[
	A simple, functional module for creating and managing icon ImageLabels from a spritesheet.
	
	This version includes optimizations to prevent redundant property setting and to
	improve code readability by caching values.
]]
local IconService = {}

-- Load the icon data from the index file. This is done only once when the module is required.
local iconIndex = require(script.index)

-- A constant for the attribute name to ensure consistency.
local ICON_ATTRIBUTE_NAME = "IconName"

-- Type definition for the data expected for a single icon in the index.
type IconData = {
	imagerectoffset: {number},
	imagerectsize: {number},
}

--[[
	Creates and returns a new ImageLabel configured with the specified icon.
	
	@param iconName The name of the icon to create.
	@return A new ImageLabel instance with the icon applied.
	@error If the icon does not exist in the index.
]]
function IconService.Get(iconName: string): ImageLabel
	local iconData: IconData = iconIndex.icons[iconName]
	if not iconData then
		error("IconService: Icon '" .. iconName .. "' does not exist.", 2)
	end

	local imageLabel = Instance.new("ImageLabel")
	
	-- Configure the ImageLabel with shared properties
	imageLabel.Image = iconIndex.image
	imageLabel.ResampleMode = Enum.ResamplerMode.Pixelated
	imageLabel.BackgroundTransparency = 1
	
	-- Apply the specific icon's properties using the ApplyTo function to avoid code duplication.
	-- The redundancy check inside ApplyTo is not strictly needed here since it's a new instance,
	-- but this keeps the logic centralized and clean.
	IconService.ApplyTo(imageLabel, iconName)
	
	return imageLabel
end

--[[
	Applies an icon's properties to an existing ImageLabel.
	This is optimized to do nothing if the requested icon is already applied.
	
	@param targetLabel The ImageLabel instance to modify.
	@param iconName The name of the icon to apply.
	@error If the icon does not exist in the index.
]]
function IconService.ApplyTo(targetLabel: ImageLabel, iconName: string)
	-- Optimization: Check the instance's attribute to see if the icon is already set.
	-- If it is, we can skip all the work.
	if targetLabel:GetAttribute(ICON_ATTRIBUTE_NAME) == iconName then
		return
	end

	local iconData: IconData = iconIndex.icons[iconName]
	if not iconData then
		error("IconService: Icon '" .. iconName .. "' does not exist.", 2)
	end
	
	-- Optimization: Cache the table values in local variables.
	-- This avoids repeated lookups (e.g., `iconData.imagerectsize`) and is slightly faster.
	local rectOffset = iconData.imagerectoffset
	local rectSize = iconData.imagerectsize

	-- Note: We only update properties that are specific to the icon.
	-- Shared properties like Image and ResampleMode are assumed to be set on creation.
	targetLabel.Size = UDim2.fromOffset(rectSize[1], rectSize[2])
	targetLabel.ImageRectOffset = Vector2.new(rectOffset[1], rectOffset[2])
	targetLabel.ImageRectSize = Vector2.new(rectSize[1], rectSize[2])
	
	-- Store the current icon name in an attribute on the instance for the next check.
	targetLabel:SetAttribute(ICON_ATTRIBUTE_NAME, iconName)
end


return IconService

Also by functional I wasn’t saying that your implementation doesn’t work whereas mine does, just meant that this works purely off functions without any OOP.

4 Likes

Updated! thanks!

keystrokes keystrokes

1 Like

how do i even download? link isnt work for me

click the rbxm link, it works for me

error showing up
why my internet provider is blocked this site?

I realize now that my file host is flawed. Will update the link soon.

Updated the link, you should be able to download now

These icons look older than me :cold_face: