{"id":43785,"library":"safesql","title":"safesql","description":"safesql is an npm package (v2.0.2) that provides ES6 template tag functions for safely composing MySQL and PostgreSQL query strings. It automatically escapes dynamic values based on context (identifiers, values, raw expressions) to prevent SQL injection. Written by Mike Samuel, a security engineer, it is part of the template-tag-common family. The library is lightweight, has no runtime dependencies, and supports both CommonJS and ESM (via bundlers). Unlike string concatenation or naive escaping, safesql uses tagged template literals to distinguish between identifiers and values, and handles arrays, objects, and nested SqlFragment instances correctly. Release cadence is low, with version 2.0.2 current as of 2024.","status":"active","version":"2.0.2","language":"javascript","source_language":"en","source_url":"https://github.com/mikesamuel/safesql","tags":["javascript","sql","security","injection","template","template-tag","string-template","sec-roadmap","es6"],"install":[{"cmd":"npm install safesql","lang":"bash","label":"npm"},{"cmd":"yarn add safesql","lang":"bash","label":"yarn"},{"cmd":"pnpm add safesql","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Available as a named export. For CommonJS, use destructuring require.","wrong":"const mysql = require('safesql').mysql","symbol":"mysql","correct":"import { mysql } from 'safesql'"},{"note":"PostgreSQL variant; same import pattern as mysql.","wrong":"const pg = require('safesql').pg","symbol":"pg","correct":"import { pg } from 'safesql'"},{"note":"Named export for the result type; not default export.","wrong":"import SqlFragment from 'safesql'","symbol":"SqlFragment","correct":"import { SqlFragment } from 'safesql'"},{"note":"Constructor for SQL identifiers; use as an alternative to backtick syntax.","symbol":"SqlId","correct":"import { SqlId } from 'safesql'"}],"quickstart":{"code":"import { mysql, SqlId } from 'safesql';\n\nconst table = 'users';\nconst userId = 1;\nconst data = { email: 'test@example.com', modified: mysql`NOW()` };\nconst query = mysql`UPDATE \\`${table}\\` SET ${data} WHERE \\`id\\` = ${userId}`;\nconsole.log(query);\n// UPDATE `users` SET `email` = 'test@example.com', `modified` = NOW() WHERE `id` = 1","lang":"javascript","description":"Demonstrates building a safe SQL UPDATE query with identifier escaping, object SET clause, and nested raw SQL via SqlFragment."},"warnings":[{"fix":"Always prefix your SQL string with the mysql or pg tag, e.g., mysql`SELECT ...` not just `SELECT ...`.","message":"Do not use regular template strings with database calls; safesql requires the template tag function to properly escape values.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Use ${} inside \\` `identifier`\\` for MySQL or \"${identifier}\" for PostgreSQL to mark identifiers.","message":"Identifiers must be wrapped in escaped backticks (for MySQL) or escaped double quotes (for PostgreSQL) at the template literal level.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Rely on safesql for escaping, but test your queries with a database to ensure correctness.","message":"The package does not validate the final SQL syntax; it only escapes values based on context. Incorrect use can still produce malformed SQL.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Use named imports: import { mysql, pg, SqlFragment, SqlId } from 'safesql'.","message":"The default export pattern (e.g., import safesql from 'safesql') is not available; only named exports exist.","severity":"deprecated","affected_versions":">=2.0.0"}],"env_vars":null,"search_vec":"'2.0.2':103 '2024':107 'array':90 'automat':23 'base':27 'bundler':70 'cadenc':98 'common':53 'commonj':66 'compos':16 'concaten':73 'context':29 'correct':96 'current':104 'depend':62 'distinguish':83 'dynam':25 'engin':44 'es6':10,122 'escap':24,76 'esm':68 'express':33 'famili':54 'function':13 'handl':89 'identifi':30,85 'inject':37,111 'instanc':95 'javascript':108 'librari':56 'lightweight':58 'liter':81 'low':100 'mike':40 'mysql':17 'naiv':75 'nest':93 'npm':5 'object':91 'packag':6 'part':47 'postgresql':19 'prevent':35 'provid':9 'queri':20 'raw':32 'releas':97 'roadmap':121 'runtim':61 'safe':15 'safesql':1,2,77 'samuel':41 'sec':120 'sec-roadmap':119 'secur':43,110 'sql':36,109 'sqlfragment':94 'string':21,72,117 'string-templ':116 'support':64 'tag':12,52,79,115 'templat':11,51,80,112,114,118 'template-tag':113 'template-tag-common':50 'unlik':71 'use':78 'v2.0.2':7 'valu':26,31,87 'version':102 'via':69 'written':38","created_at":"2026-06-05T17:01:28.281372+00:00","updated_at":"2026-06-05T17:01:28.281372+00:00","problems":[{"fix":"Change to named import: import { mysql } from 'safesql'","cause":"Using default import when only named exports are available.","error":"TypeError: safesql_1.default is not a function"},{"fix":"Ensure template literals use escaped backticks for identifiers: \\`table\\`","cause":"Using safesql on a string that contains syntax errors or unescaped backticks.","error":"Error: Invalid SQL: Unexpected token"},{"fix":"Add import: import { mysql } from 'safesql'","cause":"Incorrect import path or missing import statement.","error":"ReferenceError: mysql is not defined"},{"fix":"Run npm install safesql. TypeScript types are included via @types/safesql if needed.","cause":"Package not installed or TypeScript missing type definitions.","error":"Cannot find module 'safesql' or its corresponding type declarations."}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/mikesamuel/safesql#readme","github":"https://github.com/mikesamuel/safesql","docs":null,"changelog":null,"pypi":null,"npm":"safesql","openapi_spec":null,"status_page":null,"smithery":null,"categories":["security","database"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-05","next_check":"2026-09-03","install_tag":null}}