My KiCAD component database

Hello, everyone

About half year ago I have created a KiCAD database library for my hobby use and I want to share it. Maybe someone will find it useful and would like to create their own database or modify their own library.

Before it I just had an excel spreadsheet where I had stored information about the components I have and just used symbols and footprints from KiCAD, and add internal part number “#ID” to KiCAD component and used “lookup” excel function to fill all the other information when I extracted BoM from KiCAD. Although it was quite efficient because for most of the components I could just find symbols and footprints from KiCAD library, because I was using DB library at my work, I thought maybe I could make one for my hobby and use it instead of excel.

Excel Component Library:

Added component ID number from DBLib:

Extracted and Modified BoM:

Now I will tell you about my database library:

To create a database library I had created a dummy test library to test how it works. Then I created structure of my library.

For the structure I wanted to have several libraries in my database separated by the type of components for easier search. The libraries looks like this:

Then I needed to find out what columns I would be needed for the library. Most of the columns I have just transferred from my Excel component list and added a few. There is the list:

After that I created a database using SQLiteStudio (Instruction how to do this will be added to Github together with an example database library). My created database looks like this:

After that I had to setup my KiCAD for the database by adding new Environmental variables, setup symbol and footprint libraries and adding database to symbol libraries. I had added Visible marking in symbol libraries so that I only could use database library in project or Power Ports:


I have designed already 5 small projects with this library and I like how it turned out. There is what I have noticed using database library:

Database library pros:
• No need excel component sheet, everything is stored in database and visible directly in KiCAD
• If I find a mistake in a component information, I just need to fix it in database and update component from library in KiCAD
• Re-using component is very easy and fast
• Easy to search what component you have and can use for a project directly in KiCAD
• Attach symbols and footprint to several to several components are very easy, just copy-paste footprint or symbol name
• Easy to setup to use across several PCs or sharing library in a team (I use several laptops and just using GitHub)
• Database columns can easily be added and removed to adjust the user’s needs.
Your component can store a lot more information and it is easier to manage

Database library Cons:
• It takes some time to setup the library (for me it took about a week of work to create library structure, setup the library, transfer there all my components to it)
• When adding a lot of new components some things can be missed and noticed only when you use components in the project. Like wrong symbol or footprint name and no footprint is displayed for a component. However it’s easy to fix.
• Adding new components is not as fast as just copy-paste a resistor in a project and change a resistance value. You need to open database and add new component.
After adding new components or modifying in existing ones in a database, you need to close the KiCAD and reopen it.

Other concerns:
Q: what if I want to share my projects without sharing whole database library?
A: Create a copy of a project folder, that you want to share, then use “Export Symbols to new Library” and “Export Footprints to new Library” functions. In addition you can use “Archive 3D Models” plugin which exports and all 3D models and links them to new local footprint library. Now all project components are linked to a local project library within a project folder.
image

Q: What if I do not want to have one footprint for a component, for Example I can use THT electrolytic cap standing or bend component.
A: Just add Footprint Filters column to the database and add footprint later in a project which is filtered to display only suitable footprints.
image

Also, I want to thank the Official KiCAD Librarians as well as everyone that are contributing to the library, you guys are doing amazing job and saving hundreds of hours’ time for me and other developers.

And also I want to thank for AKL (Alternative KiCAD Library) creator Dawid Cisło for creating amazing library. I am using your component footprints and symbols a lot and they are great :slight_smile:

Most of my components symbols and footprints are either modified from Original library or AKL library, but some of them I create myself.

I added my instruction how to setup a library and my example database library to GitHub, with all the files:

Of course all criticism is welcome and I would like to hear your thoughts about it and other ideas, thanks :slight_smile:

22 Likes

This looks amazing! Thank you for making such good documentation to get this thing going.

1 Like

Glad if it is useful :slight_smile:
Thanks!

Amazing work because I’m currently making the switch from Altium to Kicad. If I may ask:

In your Global Libraries dialog you have both the database library (kicad_dbl) and the schematic symbol libraries (kicad_sym) (and I guess footprint libraries as well).

Do the kicad_sym files need to be added to the Global Library dialog as well or can those be left out for the kicad_dbl to find them?

With AD we’ve been following the One Symbol / File approach, this doesn’t seem to be useful in Kicad because you’d need to add all of those to the Global Libraries if they need to be added.

Is it common to put the symbols for a group (e.g. Passives) into a single file? Or all schematic symbols? What would you recommend?

Thank you

1 Like

Glad if it helps you to create your own DB.

In your Global Libraries dialog you have both the database library (kicad_dbl) and the schematic symbol libraries (kicad_sym) (and I guess footprint libraries as well).

Yea, as far as I have tested you need to add all the Symbol and Footprint libraries as your global libraries (I have not tested with local libraries). It is because your database will reference to those libraries.

Do the kicad_sym files need to be added to the Global Library dialog as well or can those be left out for the kicad_dbl to find them?

As far as I know, you need to add all symbol and footprint libraries that you want to reference to in your database. However, you can select that all the libraries except database library would be not visible, so this way when you will search for component in your project you will see only components from your database.

image

Is it common to put the symbols for a group (e.g. Passives) into a single file? Or all schematic symbols? What would you recommend?

I think it is common. Official KiCAD library have Device Symbol library where there is placed capacitors, resistors and other common symbols. I have separated passives into Psv_Resistors, Psv_Capacitors, Psv_Inductors and Psv_Other. This is because I like to add package to those symbols. I use separate symbols for 0402 resistors and 0603 resistors. I like this because this way I have more information on the schematics.

It more depends on how you like your schematics to look. I have worked with libraries where all the components are added into one library and after a while, when there are a lot of components, that library becomes quite messy.

I have separated my symbol libraries into:

  • Diodes
  • Transistors
  • Active_Other (Diacs, Triacs etc.)
  • Connectors
  • Integrated_Circuits
  • Modules
  • Oscillators
  • Switches
  • Devices (LCDs, Buzzers, Microphones, Antennas etc.)
  • Capacitors
  • Resistors
  • Inductors
  • Passive_Other (Fuses etc.)
  • PCB_Components (Testpoints, Mounting Holes etc.)

This seems to be working for me. Feel free if you want to do something similar. If you have any other questions I am glad to help :slight_smile:

4 Likes

Thank you, great detailed response. I’ll try to implement it the same way.

1 Like

Just wanted to give some feedback. I have successfully transferred our Altium library to a Kicad library. Also, the sym-lib-table and fp-lib-table files are generated automatically from the available files.
That’s pretty cool.

3 Likes

You don’t need separate symbols for 0402 and 0603. Just add field and put in symbol
Screenshot 2024-11-21 143204
See: the isolation working voltage is done using field. But with specified color and placement (autoplacement is disabled for this field).

Also, you may want to add marker field for SMD components
Screenshot 2024-11-21 143714

2 Likes

Glad it works for you :slight_smile:

Yea, you are right, I just like to have all my symbols with the same fields and no additional fields, but thats just my internal symbol rules.

Great idea about component marking parameters :slight_smile:

I’m not advanced enough yet to import a library but I can appreciate its usefulness. Eventually I will work with it for certain. I’m not sure if I’m just old but we used to call caps “Axial” and “Radial”. Not sure if that helps or if I just look like a jerk. :innocent: Keep up the good work!

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

@Mantvis, first of all, thank you so much for your detailed posting!

I am confused about one thing. In this earlier posting (granted, for KiCAD7; now we are on KiCAD9!), @teletypeguy extensively discusses a JSON file which translates between KiCAD and the database. @craftyjon also discussed this file in his presentation at KiCon2023 in Europe (advance the video to 7:30). I don’t see any reference to such file in your posting. Has something changed from KiCAD7?

1 Like

The *.kicad_dbl file mentioned above is the ‘database link’ file and defines how KiCad accesses and interacts with the database. It is written in JSON format (JavaScript Object Notation). Here is a useful link and further description - it is for macOS but the same principles apply for any platform and the format of the *.kidcad_dbl file is discussed.

2 Likes

Hi

I am also going to do the advanced digital design course and I noticed that XC7Z footprint/symbols arent in default kicad 7 libs… did you create your own for that course?

would have asked in the other thread but its locked :slight_smile:

1 Like

Hi,

Yes, I created the symbols and footprints for the course :slight_smile:
Some were modified original kicad libs, others I created from scratch

1 Like

@somnatic: Can you give us some details how you transferred the Altium library to KiCAD?

Sure.
We’ve been using a DbLib in Altium for years. The table format is in fact very similar; I just had to create a new table based on the data we already had in there. The reason for that is that KiCad typically uses multiple parts per file for schematic symbols while we were using single part per file in Altium. That’s one of my pet peeves which is better in Altium because it enables nicer version control of parts. That was the easy part.

That’s the schema for the database:

USE [KicadLibrary]
GO

/****** Object:  Table [dbo].[Parts]    Script Date: 24.06.2025 08:20:45 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Parts](
	[Ident] [nvarchar](32) NOT NULL,
	[Symbols] [nvarchar](512) NULL,
	[Footprints] [nvarchar](512) NULL,
	[Description] [nvarchar](512) NULL,
	[ValueA] [nvarchar](256) NULL,
	[ValueB] [nvarchar](256) NULL,
	[CheckedBy] [nvarchar](16) NULL,
	[CheckedOn] [datetime] NULL,
	[CreatedBy] [nvarchar](16) NULL,
	[CreatedOn] [datetime] NULL,
	[Datasheet1Uri] [nvarchar](256) NULL,
	[Datasheet2Uri] [nvarchar](256) NULL,
	[Datasheet3Uri] [nvarchar](256) NULL,
	[Manufacturer1] [nvarchar](128) NULL,
	[Manufacturer2] [nvarchar](128) NULL,
	[Manufacturer3] [nvarchar](128) NULL,
	[Manufacturer4] [nvarchar](128) NULL,
	[Manufacturer5] [nvarchar](128) NULL,
	[ManufacturerPartNumber1] [nvarchar](128) NULL,
	[ManufacturerPartNumber2] [nvarchar](128) NULL,
	[ManufacturerPartNumber3] [nvarchar](128) NULL,
	[ManufacturerPartNumber4] [nvarchar](128) NULL,
	[ManufacturerPartNumber5] [nvarchar](128) NULL,
	[Package] [nvarchar](128) NULL,
	[PackageGroup] [nvarchar](1) NULL,
 CONSTRAINT [PK_Parts] PRIMARY KEY CLUSTERED 
(
	[Ident] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

The symbols and footprints can be converted to KiCad format automatically. For symbols, you will need to use the one file contains many parts methods because you will need to add the files to the library in Kicad (you cannot simply add the kicad_dbl file and expect it to find your symbols - this should be changed in Kicad). For footprints it was easier as it’s the same here, just the folders are named .pretty.

This is the C# code for converting your symbols and footprints to kicad format (we’re using the kicad-cli)

            Console.WriteLine("Schematic Symbols");
            foreach (var schLibFile in Directory.GetFiles(baseAltiumPathSch, "*.schlib", SearchOption.AllDirectories))
            {
                FileInfo fi = new FileInfo(schLibFile);
                var pathAltium = fi.DirectoryName;
                if (pathAltium == null)
                {
                    throw new Exception("Invalid");
                }
                var pathKicad = pathAltium.Replace(baseAltiumPathSch, baseKicadPathSch);
                var filenameKicad = fi.Name.Replace(".schlib", ".kicad_sym", true, CultureInfo.InvariantCulture);
                var fullFilename = Path.Combine(pathKicad, filenameKicad);

                Directory.CreateDirectory(pathKicad);

                ProcessStartInfo psi = new ProcessStartInfo();
                psi.FileName = kicadCliExecutable;
                psi.UseShellExecute = false;
                psi.RedirectStandardOutput = true;
                psi.RedirectStandardError = true;

                var argumentsList = $"sym upgrade --output \"{fullFilename}\" \"{schLibFile}\"";
                psi.Arguments = argumentsList;

                Process process = new Process();
                process.StartInfo = psi;
                process.Start();

                process.WaitForExit(10000);

                if (process.ExitCode != 0)
                {
                    Console.Write($"{process.ExitCode}");
                    Console.WriteLine(" " + process.StandardOutput.ReadToEnd());
                    Console.WriteLine(" " + process.StandardError.ReadToEnd());
                }
            }

From that you build the library file for Kicad:

// Build the sym-lib-table file

SNodeList libList = new SNodeList
{
    Items = []
};
SExpression sexKicadSymLibTable = new SExpression("sym_lib_table", libList.Items);
libList.Items.Add(new SExpression("version", 7));


var dbLibEntry = new SNodeList
{
    Items = []
};
dbLibEntry.Items.Add(new SExpression("name", "kicad_db"));
dbLibEntry.Items.Add(new SExpression("type", "Database"));
dbLibEntry.Items.Add(new SExpression("uri", "${KICAD8_SYMBOL_DIR}/kicad_db.kicad_dbl"));
dbLibEntry.Items.Add(new SExpression("options", ""));
dbLibEntry.Items.Add(new SExpression("descr", ""));
libList.Items.Add(new SExpression("lib", dbLibEntry.Items));

foreach (var file in Directory.GetFiles(baseKicadPathSch, "*.kicad_sym", SearchOption.TopDirectoryOnly))
{
    FileInfo fi = new FileInfo(file);
    var innerLib = new SNodeList
    {
        Items = []
    };
    innerLib.Items.Add(new SExpression("name", fi.Name.Replace(".kicad_sym", "")));
    innerLib.Items.Add(new SExpression("type", "KiCad"));
    innerLib.Items.Add(new SExpression("uri", fi.FullName.Replace("/", "\\")));
    innerLib.Items.Add(new SExpression("options", ""));
    innerLib.Items.Add(new SExpression("descr", ""));
    innerLib.Items.Add(new SNodeList()
    {
        Items = new List<SNodeBase> { new SNodeAtom("hidden") }
    });
    libList.Items.Add(new SExpression("lib", innerLib.Items));

}

sexKicadSymLibTable.WriteToFile(kicadSymLibTable);

This is the code for the footprints

            // Footprints, we need to handle the subfolders differently here
            // Console.WriteLine("Footprints");
            foreach (var pcbLibFile in Directory.GetFiles(baseAltiumPathPcb, "*.pcblib", SearchOption.AllDirectories))
            {
                // Get the first directory they are in, cannot go deeper than 1 folder
                FileInfo fi = new FileInfo(pcbLibFile);
                var filenameKicad = fi.Name.Replace(".pcblib", ".kicad_mod", true, CultureInfo.InvariantCulture);

                var directories = pcbLibFile.Split(Path.DirectorySeparatorChar);

                var directory = directories[3];
                directory += ".pretty";

                if (Directory.Exists(temporaryConversionFileName))
                {
                    Directory.Delete(temporaryConversionFileName, true);
                }



                var folder = Path.Combine(baseKicadPathPcb, directory);

                Directory.CreateDirectory(folder);

                //var destinationFullFilename = Path.Combine(folder, filenameKicad);



                ProcessStartInfo psi = new ProcessStartInfo();
                psi.FileName = kicadCliExecutable;
                psi.UseShellExecute = false;
                psi.RedirectStandardOutput = true;
                psi.RedirectStandardError = true;

                var argumentsList = $"fp upgrade --output \"{temporaryConversionFileName}\" \"{pcbLibFile}\"";
                psi.Arguments = argumentsList;

                Process process = new Process();
                process.StartInfo = psi;
                process.Start();

                process.WaitForExit(10000);

                if (process.ExitCode != 0)
                {
                    Console.Write($"{process.ExitCode}");
                    Console.WriteLine(" " + process.StandardOutput.ReadToEnd());
                    Console.WriteLine(" " + process.StandardError.ReadToEnd());

                    continue;
                }

                // This has now created a library, but we need the file from inside that library
                var innerFileName = Path.Combine(temporaryConversionFileName, filenameKicad);

                var destinationFilename = Path.Combine(folder, filenameKicad);

                File.Move(innerFileName, destinationFilename);

            }


From that, you build the footprint library file for Kicad

            SNodeList fbList = new SNodeList
            {
                Items = []
            };
            SExpression sexKicadFpLibTable = new SExpression("fp_lib_table", fbList.Items);

            foreach (var dir in Directory.GetDirectories(baseKicadPathPcb, "*.pretty", SearchOption.TopDirectoryOnly))
            {
                DirectoryInfo di = new DirectoryInfo(dir);
                var innerLib = new SNodeList
                {
                    Items = []
                };
                innerLib.Items.Add(new SExpression("name", di.Name.Replace(".pretty", "")));
                innerLib.Items.Add(new SExpression("type", "KiCad"));
                innerLib.Items.Add(new SExpression("uri", di.FullName.Replace("/", "\\")));
                innerLib.Items.Add(new SExpression("options", ""));
                innerLib.Items.Add(new SExpression("descr", ""));
                //innerLib.Items.Add(new SNodeList()
                //{
                //    Items = new List<SNodeBase> { new SNodeAtom("hidden") }
                //});
                fbList.Items.Add(new SExpression("lib", innerLib.Items));

            }

            sexKicadFpLibTable.WriteToFile(kicadFpTable);


And here is the code that creates the table from the parts


List<Part> parts = new List<Part>();

// Build a dictionary which part can be found in which library (schematic symbols)
Dictionary<string, string> symLibLocations = new Dictionary<string, string>();

foreach (var kicadSymLibFile in Directory.GetFiles(@"A:\libs_kicad\SCH", "*.kicad_sym", SearchOption.TopDirectoryOnly))
{
    // Load the symbols in that file
    SExpression sexSymLibFile = new SExpression();
    sexSymLibFile.LoadFromFile(kicadSymLibFile);

    string symLibName = new FileInfo(kicadSymLibFile).Name.Replace(".kicad_sym", "");

    foreach (var item in sexSymLibFile.Items.Where(d => d is SExpression && ((SExpression)d).Name == "symbol"))
    {
        var sItem = (SExpression)item;
        var value = sItem.GetValue();
        symLibLocations.Add(value, symLibName + ":" + value);
    }
}

// Build a dictionary which part can be found in which library (footprints)
Dictionary<string, string> fpLibLocations = new Dictionary<string, string>();

foreach (var kicadFpLibDirectory in Directory.GetDirectories(@"A:\libs_kicad\PCB", "*.pretty", SearchOption.TopDirectoryOnly))
{
    var libName = new DirectoryInfo(kicadFpLibDirectory).Name.Replace(".pretty", "");

    foreach (var file in Directory.GetFiles(kicadFpLibDirectory, "*.kicad_mod", SearchOption.TopDirectoryOnly))
    {
        FileInfo fi = new FileInfo(file);
        var fpName = fi.Name.Replace(".kicad_mod", "");
        fpLibLocations.Add(fpName, libName + ":" + fpName);
    }
}


foreach (var erpPart in erpArticles.Where(d=>!string.IsNullOrEmpty(d.Value.SchematicReference)))
{
    var part = new Part();

    part.Ident = erpPart.Key;
    part.CreatedBy = erpPart.Value.CreatedBy;
    part.CreatedOn = erpPart.Value.CreatedOn;
    part.CheckedBy = erpPart.Value.CheckedBy;
    part.CheckedOn = erpPart.Value.CheckedOn;
    part.Datasheet1Uri = erpPart.Value.Datasheet1Uri;
    part.Datasheet2Uri = erpPart.Value.Datasheet2Uri;
    part.Datasheet3Uri = erpPart.Value.Datasheet3Uri;
    part.Description = erpPart.Value.DescriptionLong;

    if (symLibLocations.ContainsKey(erpPart.Value.SchematicReference))
    {
        part.Symbols = symLibLocations[erpPart.Value.SchematicReference];
    }
    else
    {
        Console.WriteLine($"{part.Ident}: Symbol {erpPart.Value.SchematicReference} nicht gefunden");
    }

    var footprints = new List<string>
    {
        (erpPart.Value.FootprintReference),
        (erpPart.Value.FootprintReference2),
        (erpPart.Value.FootprintReference3)
    }.Where(d => !string.IsNullOrWhiteSpace(d));

    List<string> foundFootprints = new List<string>();
    foreach (var footprint in footprints)
    {
        if (fpLibLocations.TryGetValue(footprint, out var location))
        {
            foundFootprints.Add(location);
        }
        else
        {
            Console.WriteLine($"{part.Ident}: FP {footprint} nicht gefunden");
        }
    }
    part.Footprints = string.Join(",", foundFootprints);

    part.Manufacturer1 = erpPart.Value.Manufacturer1;
    part.Manufacturer2 = erpPart.Value.Manufacturer2;
    part.Manufacturer3 = erpPart.Value.Manufacturer3;
    part.Manufacturer4 = erpPart.Value.Manufacturer4;
    part.Manufacturer5 = erpPart.Value.Manufacturer5;
    part.ManufacturerPartNumber1 = erpPart.Value.ManufacturerPartNumber1;
    part.ManufacturerPartNumber2 = erpPart.Value.ManufacturerPartNumber2;
    part.ManufacturerPartNumber3 = erpPart.Value.ManufacturerPartNumber3;
    part.ManufacturerPartNumber4 = erpPart.Value.ManufacturerPartNumber4;
    part.ManufacturerPartNumber5 = erpPart.Value.ManufacturerPartNumber5;
    part.Package = erpPart.Value.Package;
    part.PackageGroup = erpPart.Value.PackageGroup;

    parts.Add(part);
}

using var kicadLibrary = new KicadLibraryContext();
kicadLibrary.Parts.RemoveRange(kicadLibrary.Parts);

kicadLibrary.Parts.AddRange(parts);

kicadLibrary.SaveChanges();

The whole thing is currently a proof on concept. We’re not using it in production right now but I could successfully place parts in Kicad and the footprints were tied in as well. It sure needs some fine tweaking if it’s going into production but I’d like to see some changes in Kicad before we’re actually making the switch:

I think I wrote about these in another post but in general I’d like to use the one part / file strategy and not have to add each symlib library file to the Kicad library manager. Just add the kicad_dbl file and you should be done.

I hope that helps; I know it’s a bit unstructured but it’s a proof-of-concept which worked quite fine. Certainly you’ll need to tie it to your requirements. The SExpression code and CParser code were both taken from GitHub - bobc/eakit: A tool to convert EAGLE(tm) CAD projects to KiCad.

3 Likes