# iTextSharp.LGPLv2.Core is the last LGPL window into iTextSharp for .NET

> This repository is an unofficial port of iTextSharp 4.1.6, the last version published under LGPL, to .NET Core. It exists because the LGPL option was closed off in later versions, and the price of using it is an old API surface with known gaps and a SkiaSharp dependency on Linux.

**VahidN/iTextSharp.LGPLv2.Core** — iTextSharp.LGPLv2.Core  is an unofficial port of the last LGPL version of the iTextSharp (V4.1.6) to .NET Core

- Repository: https://github.com/VahidN/iTextSharp.LGPLv2.Core
- Stars: 679 · Forks: 168
- Language: C#
- License: NOASSERTION
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/vahidn-itextsharp-lgplv2-core

## An unofficial port of a version that is legally frozen

iTextSharp.LGPLv2.Core is described in the README as an unofficial port of the last LGPL version of iTextSharp, version 4.1.6, to .NET Core. Three words in that sentence carry the weight. Unofficial means the port is not sanctioned by the upstream iTextSharp project, so there is no upstream commitment to it. LGPL version means the licensing was the deciding factor rather than the features. And 4.1.6 means the API surface is old.

The upstream source it is ported from is the iTextSharp 4.1.6 repository, and the licence it is porting is LGPL 2.0, linked in the README. The topics attached to the repository name the context: asp-net-core, aspnetcore, itextsharp and pdf.

Who needs this is fairly specific. A team with an existing .NET application that generates PDFs through the old iTextSharp API, and a legal requirement or an organisational policy that rules out AGPL code or a commercial licence, is the audience. The alternative, an application that is free to use AGPL or to buy a licence, has better options available to it.

The pragmatic reality of most such ports is that the code compiles on a modern runtime, the API behaves as it did in the original, and the gaps are the gaps the original had. The README's own FAQ is a good catalogue of those gaps, and it is more useful than any feature list would be.

## Three licence choices upstream, and only one open door

The licensing section explains the situation more clearly than the introduction does. There are three licence choices for iTextSharp: LGPL/MPL, AGPL, or a commercial licence. The LGPL/MPL option is only available with the older 4.1.6 version, which is the one this project is based on. After that version, upstream moved to a dual AGPL and commercial model.

The consequence the README states plainly: if you need a more recent version, you either have to make your project open source or pay the licence fee. That is the entire reason this port exists. It is a way to keep LGPL terms while getting the code onto .NET Core, at the cost of staying on a 2013 era API.

The repository itself carries a LICENSE.md file, and the project record classifies the licence as one that GitHub could not classify, a custom licence rather than a recognised identifier. Read that file before shipping anything, because the upstream LGPL terms and the terms of this port are two separate documents, and the port's own file is the one that governs your use of the port.

There is also a build script called tag-it.bat at the repository root, next to update-dependencies.bat, which suggests the project manages its own release tagging and dependency updates outside the GitHub releases UI. Consistent with that, the repository has no GitHub releases, so the version history lives in the NuGet package page rather than in tags you would find on the repository.

## Installing the package from NuGet

Installation is a single command in the Package Manager Console, and the README gives it exactly:

```bash
PM> Install-Package iTextSharp.LGPLv2.Core
```

The package page is on NuGet, and the README links it for the version and download listing.

That is the whole install story on Windows, where the original iTextSharp code was first written and where the port is most likely to behave exactly as the older library did. The repository has no GitHub releases, so the NuGet page is the place to check which version you are pulling, and the README's own links to the functional tests and to the sample code point at the repository as the source of usage examples.

The functional tests live in a directory of their own under src, and the FAQ links into specific example files by line, which is how you learn the idioms for this API. The Unicode font question in the FAQ, for instance, points at a specific chapter of the examples, and the HtmlWorker question points at the test file where the class is used. For a port of an old library, those example files are the documentation.

The repository is organised as a modern .NET solution, with a .slnx solution file and a global.json, which is what pins the SDK version the build expects. The src/ directory holds the project and the functional test project side by side.

## Linux and containers need SkiaSharp natives and an MSBuild copy step

Running this on Linux is the part that needs extra work, and the README is upfront about it. The SkiaSharp library needs extra dependencies to work on Linux and in containers, and the package to install is:

```bash
PM> Install-Package SkiaSharp.NativeAssets.Linux.NoDependencies
```

The NoDependencies variant matters. It is the build of the native library that does not pull in the platform's own graphics dependencies, which is what makes it usable inside a slim container image where those libraries are absent.

There is a second step, and the README explains that it exists because of how .NET loads these files. You have to add MSBuild directives to your .csproj file so the native library ends up in the right place after publishing:

```xml
<Target Name="CopyFilesAfterPublish" AfterTargets="AfterPublish">
    <Copy SourceFiles="$(TargetDir)runtimes/linux-x64/native/libSkiaSharp.so" DestinationFolder="$([System.IO.Path]::GetFullPath('$(PublishDir)'))/bin/" />
</Target>
```

The target runs after publish and copies the linux-x64 native library into the bin directory of the published output. The README notes that these extra steps are normally not required but that there seem to be some issues with how .NET loads them, so this is a workaround rather than a documented convention, and the wording of that note is worth weighing.

Two practical limits follow. The copy target names linux-x64 specifically, so an arm64 container needs its own handling. And the copy is tied to the publish path rather than to a run-from-source path, so a container that runs the app from the build output rather than from the publish output will need the file placed some other way.

## The FAQ is a list of things 4.1.6 cannot do

The most useful section of the README for a would-be user is the FAQ, because it lists the boundaries of the ported version rather than the features.

First, the file lock. The question is that the PDF is created but a viewer says the document is in use by another process. The answer is to dispose the FileStream or MemoryStream explicitly, because the file is not closed and disposed automatically at the end. On a long running service that is a genuine resource leak if you ignore it.

Second, PdfTextExtractor does not exist here. The README says it was introduced in version 5.0.2 under the AGPL licence, and that this project is based on the 4.x line rather than 5.x. So text extraction, a feature most people reach for a PDF library to get, is outside the LGPL surface.

Third, table rowspans do not work correctly. The README says iTextSharp supports row spans correctly from version 5.4.3, not before, and suggests the workaround for this version: use nested tables to simulate the rowspan. That is a documented correctness gap in a feature that matters for any report layout.

Fourth, HTMLWorker does not exist under its old name. The class was renamed to HtmlWorker, with a link to the test that uses it.

And fifth, Unicode characters do not display by default, with the fix being to define and use a Unicode font, with samples in the examples. Combined with the missing text extractor, the picture is of a library that can write PDF structures competently but whose text handling and table layout are behind where the newer versions are.

## What to use instead, and what it costs

The alternative is not another port, it is the licence decision. If you can accept AGPL, upstream iTextSharp 5.x and later give you PdfTextExtractor, correct row spans from 5.4.3, and an API that is still being developed, at the price of the copyleft obligation. If you can pay, the commercial licence removes the obligation and keeps the newer API. Both are stated in the README's licensing section, and both are strictly better on the feature side, which is why the LGPL route here is a legal workaround rather than a technical preference.

There is a third option that the README does not mention but that follows from its own facts: a different PDF library entirely under a permissive licence, which decouples you from iText's licensing cycle altogether. The cost of that route is that the 4.x API you already have does not carry over, so it is only a real choice for code you are writing rather than code you already have.

The decision therefore comes down to the age of the code in front of you. If a codebase already calls iTextSharp 4.x APIs and you cannot change its licence terms, this port saves a rewrite, and the FAQ tells you exactly which features will not work. If you are starting fresh or can move the licence, an LGPL-frozen port is the wrong tool, because you would be designing against a 2013 API on day one and inheriting its gaps by choice.

## Conclusion

Adopt iTextSharp.LGPLv2.Core if you have an existing .NET codebase that already uses the iTextSharp 4.x API, you need to keep that code under LGPL terms, and you can live with the gaps the README lists, including no PdfTextExtractor and no working table rowspans. Do not adopt it for a new project, because you would be starting on a port of a version frozen in 2013 and inheriting its limitations instead of designing around current APIs. Before you start, confirm that 4.1.6 behaviour is what your code needs, plan the Linux and container path with the SkiaSharp native assets package and the MSBuild copy target, and read the licensing section, since later iText versions are AGPL or commercial and the repository record does not classify the licence file.

## FAQ

### How do I install iTextSharp.LGPLv2.Core?

Run `PM> Install-Package iTextSharp.LGPLv2.Core` in the Package Manager Console. The package is published on NuGet, and the README links the package page for version information.

### Does iTextSharp.LGPLv2.Core work on Linux and in containers?

With extra steps, yes. The README says the SkiaSharp library needs extra dependencies, so you install `SkiaSharp.NativeAssets.Linux.NoDependencies` and add an MSBuild target to your .csproj that copies libSkiaSharp.so from the linux-x64 runtimes directory into the published bin folder.

### Why is PdfTextExtractor missing from iTextSharp.LGPLv2.Core?

The README states that PdfTextExtractor exists from iTextSharp 5.0.2 under the AGPL licence, and that this project is based on the 4.x line, so text extraction is not part of the LGPL port.

### What licence applies to iTextSharp.LGPLv2.Core?

The port is based on the LGPL version of iTextSharp 4.1.6, and the repository carries a LICENSE.md file whose terms the project record could not classify. Later iTextSharp versions are only available under AGPL or a commercial licence, so read the LICENSE file in the repository before distributing anything.

## Sources

- [Issues](https://github.com/VahidN/iTextSharp.LGPLv2.Core/issues)
- [README](https://github.com/VahidN/iTextSharp.LGPLv2.Core/blob/master/README.md)
- [VahidN/iTextSharp.LGPLv2.Core on GitHub](https://github.com/VahidN/iTextSharp.LGPLv2.Core)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/vahidn-itextsharp-lgplv2-core
