A Plugin Is Just a Folder

The layout

scratchpad.nvim/
  lua/
    scratchpad/
      init.lua
  doc/
    scratchpad.txt
  README.md

Anything in lua/ becomes requirable once the folder is on the runtime path. require("scratchpad") loads lua/scratchpad/init.lua.

The module pattern

local M = {}

function M.setup(opts)
  M.config = vim.tbl_deep_extend("force", defaults, opts or {})
end

return M

A table, functions on it, return M at the end. That is the whole convention — setup(opts) is a habit, not a requirement.

Loading it while you develop

{ dir = "~/projects/scratchpad.nvim", config = function() require("scratchpad").setup({}) end }

dir points lazy.nvim at a local folder instead of a GitHub repo, so you edit and restart.