SlideShare a Scribd company logo
"Building intuitive command-line interfaces in .NET", Alex Thissen
The rise of CLIs
Graphical User Interface Command-line Interface
Efficiency
Fast and simple
interaction model
Low level access
in single line
commands
Basic text-driven
command line
Automation
Scriptable
Integration in CI/CD
pipelines
Cross-platform
Terminal-based or
headless environments
do not have GUI
Allows porting to
Windows, Linux and
MacOS
User experience
Rich UI and UX
Many visualizations
Examples of CLIs and tools
CLIs
dotnet
az
docker
kubectl
tye
git
npm
Tools
curl
python
Interactive
netsh
mssql-cli
telnet
Demo
Exploring CLIs
Easter egg: Windows Terminal Quake Mode: + `
Command syntax
ale.exe .Zarlor.lnx --magnification 3 –f --controller keyboard
Options
- Key-value pairs
- Short and long form names
- Delimited by space, colon or equal sign
- Style: POSIX -- or Windows /
- Combine single char option
- Arity
Arguments
- Required values in
specific order
- Arity (unary, binary, …)
Command-line lifecycle
Parsing and invoking
Tokenization
Value conversion
Create context
Execution
Run middleware pipeline
Handler run logic
Building and preparing
Define commands,
arguments and options
Configuration
Input
Command-line
Response file
Tab-completion
Feedback
Progress updates
Prompting
Rendering output
Termination
Exception handling
Return exit codes
Report errors
Provide help and suggestions
Host process
Implementing CLIs in .NET
Application code
Recommended packages
• System.CommandLine
• CliFx
• Spectre.Console.Cli
• CommandLineParser
Terminal
or script
System.CommandLine object model
Prepare commands Build command-line Symbols
Hierarchy of symbols
Name (and aliases for
identifier symbols)
Other types
Parse & Invoke
Demo
Building command-lines and parsers
Create commands, arguments and options
Command handling
Provide handler function per command
Create handler using factory methods
Delegate or separate function
Model binding used by default
rootCommand.Handler = CommandHandler.Create<InvocationContext, int, bool>(
(context, magnification, fullScreen) =>
{
context.Console.Out.Write($"Magnification: {magnification} FullScreen {fullScreen}");
});
Middleware pipeline
ExceptionHandler
Out-of-the-box
1. CancelOnProcessTermination
2. ExceptionHandler
3. EnvironmentVariableDirective
4. ConfigureConsole
5. RegisterWithDotnetSuggest
6. DebugDirective
7. ParseDirective
8. SuggestDirective
Out-of-the-box
9. TypoCorrections
10. VersionOption
11. HelpOption
Configuration Default ErrorReporting
Your middleware logic
Invocation context
Out-of-the-box
12. ParseErrorReporting
Registering middleware
Extension methods on CommandLineBuilder
Resembles ASP.NET Core middleware
Various Use… methods
Prioritize with MiddlewareOrder enumeration
Parser parser = new CommandLineBuilder(rootCommand)
.UseDefaults()
.UseMiddleware(async (context, next) =>
{
// Execute your middleware logic here
await next(context);
}, MiddlewareOrder.ErrorReporting)
.Build();
Order of registration
More than one custom
middleware allowed
Beware of defaults
Production version might need to
skip some default middleware
(for example: directives)
ale.exe .Zarlor.lnx –-full-screen -m 3 --controller keyboard
Model binding
Run(FileInfo gameRom, int magnification, bool fullScreen, ControllerType controller)
In-order named arguments Named options
Case insensitive
Kebab casing supported
Ignores hyphens and other prefixes
Boolean, enumerations (case-insensitive)
Enumerable types (arrays, lists, …)
String based constructors (FileInfo, DirectoryInfo, Uri)
Complex types (based on properties or constructor)
Data types conversion
Special types are bound automatically
IConsole Abstraction for out and err
ParseResult All results of parsing tokens command-line
CancellationToken Cancel async tasks
BindingContext Captures converted typed values
InvocationContext Combines all of the above
Run( … , ControllerType controller, BindingContext context, CancellationToken token)
Simply add to
command handler signature
Demo: Advanced scenarios
Error handling and termination
Middleware
Subcommands and global options
Common patterns
Making it intuitive
Intuitive
CLIs
CLI-first
approach
Standards and
conventions
Simplicity
Discoverability
Offer help and documentation from CLI
Defaults save time and better for learning
Suggestions and typo corrections
Familiar names of
arguments and options
Default to stderr and
stdout
First client application is a CLI
More human-oriented:
Ad-hoc tasks and quick
Split a complex system into many
small functions
Assign each function into a
simple command
Help
Get contextual help
for free
Description
Available names
Required and arity
Allowed values and default value
Provide custom help
Create your own help builder
Register with .UseHelp<THelpBuilder>
Suggestions and typo corrections
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentSession
dotnet tool install --global dotnet-suggest --version 1.1.221601
Terminal session Interactive Host process
PowerShell
bash
zsh
dotnet-
suggest
Global dotnet tool
• Shell completions (aka tab completions)
• Register small script in bash or PowerShell profile
Suggestion sources
• Enums and known values automatically added
• Can add custom suggestions through
ISuggestionSource
Pro tip:
DOTNET_SUGGEST_LOGGING 1
DOTNET_SUGGEST_SCRIPT_VERSION 1.0.1
Debugging tips
Use [debug] directive
Attach debugger to start debug session from terminal
Pass arguments from dotnet to your CLI
{
"profiles": {
"AdvancedCLI": {
"commandName": "Project",
"commandLineArgs": "help",
"environmentVariables": {
"DOTNET_COMMANDLINE_DEBUG_PROCESSES": "ale"
ale.exe [debug] .Zarlor.lnx --magnification 3 –f --controller keyboard
dotnet run -- .Zarlor.lnx --magnification 3 –f --controller keyboard
Possible error
Debug directive specified, but no process names are listed as allowed for debug.
Add your process name to the 'DOTNET_COMMANDLINE_DEBUG_PROCESSES' environment variable.
The value of the variable should be the name of the processes, separated by a semi-colon
';', for example 'DOTNET_COMMANDLINE_DEBUG_PROCESSES=ale'
Hint:
Try [parse] and [suggest]
Photo by Pavel Mata on Unsplash
DragonFruit
Quick and easy way to create a simple CLI
Add reference to NuGet package System.CommandLine.DragonFruit
Change Main method to include typed arguments
Must return void, int, Task or Task<int>
Provide XML documentation as help information
static int Main(FileInfo gameRom, bool fullScreen = false, int magnification = 4,
ControllerType controller = ControllerType.Keyboard, FileInfo bootRom = null)
/// <summary>
/// Atari Lynx Emulator from DragonFruit
/// </summary>
/// <param name="gameRom">Game ROM filename</param>
/// <param name="fullScreen">Run emulator fullscreen</param>
Demo
DragonFruit CLIs
Debugging
Using directives
Console is not your average console
Error, Out and In should be used
Avoid System.Console
Use provided abstraction instead (IConsole)
TestConsole in unit tests
Respect redirection
Input might come from response file
Output might be sent to file or elsewhere
Test output with pipes
Output and rendering
Convenient:
Include System.CommandLine.IO for
extension methods on Error and Out
Terminal GUIs for CLIs
Rich interaction with user
Remember:
CLI != GUI
Comparing CLI frameworks (opinionated)
System.CommandLine Spectre.Console.Cli CommandLineParser CliFx
Hierarchical
commands
Yes Yes Limited Yes
Suggestions and
typo corrections
Yes No No No
Help Autogenerated Autogenerated Autogenerated Autogenerated
Target framework .NET Standard 2.0 .NET Standard 2.0
.NET 5.0
.NET Standard 2.0
.NET 4.0, 4.5, 4.6.1
.NET Standard 2.0, 2.1
Version 2.0.0-beta1.21308.1 0.49.0 2.9.0-preview1 2.0.6
Maintainer activity
Binding ++ + + ++
Host integration ++ + - ++
Directives debug, parse, config None None debug, parse
Summary
{DevOps}
$ CLI <3 .NET --always
Questions and Answers
During Discord Q&A session
Maybe later?
@alexthissen
athissen@xpirit.com
Resources
https://github.com/dotnet/command-line-api
https://github.com/Tyrrrz/CliFx
https://spectreconsole.net/
https://www.microsoft.com/en-us/p/windows-terminal
https://dotnet.microsoft.com/
https://dotnetfoundation.org/projects
https://visualstudio.microsoft.com/
https://github.com/alexthissen/modernclis
https://github.com/alexthissen/atarilynxemulator

More Related Content

DOCX
Contoh resensi buku
PPTX
Teks Anekdot - Bahasa Indonesia SMA Kelas XI
PDF
Ringkasan, Abstrak, dan Sintesis (Pengertian, Contoh, dan Kaidah Penulisan).pdf
PPTX
Desentralisasi Asimetris Ditinjau dari Dimensi Kelembagaan & Hubungan Pusat-D...
PPTX
Hikayat
PPTX
PPT teks editorial 2022 sprvsi.pptx
PPTX
Ideologi sosial masyarakat
PPT
Virtual platform
Contoh resensi buku
Teks Anekdot - Bahasa Indonesia SMA Kelas XI
Ringkasan, Abstrak, dan Sintesis (Pengertian, Contoh, dan Kaidah Penulisan).pdf
Desentralisasi Asimetris Ditinjau dari Dimensi Kelembagaan & Hubungan Pusat-D...
Hikayat
PPT teks editorial 2022 sprvsi.pptx
Ideologi sosial masyarakat
Virtual platform

Similar to "Building intuitive command-line interfaces in .NET", Alex Thissen (20)

PPT
DOCX
 Test system architectures using advanced standardized test languages
PPT
Attributes & .NET components
PDF
Activity 5
PPT
NNUG Certification Presentation
PPT
Chapter11
PPT
Powershell Seminar @ ITWorx CuttingEdge Club
PDF
Unmanaged Parallelization via P/Invoke
PPTX
Hack an ASP .NET website? Hard, but possible!
PDF
Test System Architectures using Advanced Standardized Test Languages
ODP
PostgreSQL 8.4 TriLUG 2009-11-12
PPTX
PPTX
The GO Language : From Beginners to Gophers
PPT
Sedna XML Database: Executor Internals
PPT
Advanced driver debugging (13005399) copy
PDF
Linux introduction Class 03
ODP
Alexandre Iline Rit 2010 Java Fxui
PPTX
cs262_intro_slides.pptx
PPT
MDA with Executable UML
PPTX
PowerShell-1
 Test system architectures using advanced standardized test languages
Attributes & .NET components
Activity 5
NNUG Certification Presentation
Chapter11
Powershell Seminar @ ITWorx CuttingEdge Club
Unmanaged Parallelization via P/Invoke
Hack an ASP .NET website? Hard, but possible!
Test System Architectures using Advanced Standardized Test Languages
PostgreSQL 8.4 TriLUG 2009-11-12
The GO Language : From Beginners to Gophers
Sedna XML Database: Executor Internals
Advanced driver debugging (13005399) copy
Linux introduction Class 03
Alexandre Iline Rit 2010 Java Fxui
cs262_intro_slides.pptx
MDA with Executable UML
PowerShell-1
Ad

More from Fwdays (20)

PDF
"Mastering UI Complexity: State Machines and Reactive Patterns at Grammarly",...
PDF
"Effect, Fiber & Schema: tactical and technical characteristics of Effect.ts"...
PPTX
"Computer Use Agents: From SFT to Classic RL", Maksym Shamrai
PPTX
"Як ми переписали Сільпо на Angular", Євген Русаков
PDF
"AI Transformation: Directions and Challenges", Pavlo Shaternik
PDF
"Validation and Observability of AI Agents", Oleksandr Denisyuk
PPTX
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
PPTX
"Co-Authoring with a Machine: What I Learned from Writing a Book on Generativ...
PPTX
"Human-AI Collaboration Models for Better Decisions, Faster Workflows, and Cr...
PDF
"AI is already here. What will happen to your team (and your role) tomorrow?"...
PPTX
"Is it worth investing in AI in 2025?", Alexander Sharko
PDF
''Taming Explosive Growth: Building Resilience in a Hyper-Scaled Financial Pl...
PDF
"Scaling in space and time with Temporal", Andriy Lupa.pdf
PDF
"Database isolation: how we deal with hundreds of direct connections to the d...
PDF
"Scaling in space and time with Temporal", Andriy Lupa .pdf
PPTX
"Provisioning via DOT-Chain: from catering to drone marketplaces", Volodymyr ...
PPTX
" Observability with Elasticsearch: Best Practices for High-Load Platform", A...
PPTX
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
PPTX
"Istio Ambient Mesh in production: our way from Sidecar to Sidecar-less",Hlib...
"Mastering UI Complexity: State Machines and Reactive Patterns at Grammarly",...
"Effect, Fiber & Schema: tactical and technical characteristics of Effect.ts"...
"Computer Use Agents: From SFT to Classic RL", Maksym Shamrai
"Як ми переписали Сільпо на Angular", Євген Русаков
"AI Transformation: Directions and Challenges", Pavlo Shaternik
"Validation and Observability of AI Agents", Oleksandr Denisyuk
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
"Co-Authoring with a Machine: What I Learned from Writing a Book on Generativ...
"Human-AI Collaboration Models for Better Decisions, Faster Workflows, and Cr...
"AI is already here. What will happen to your team (and your role) tomorrow?"...
"Is it worth investing in AI in 2025?", Alexander Sharko
''Taming Explosive Growth: Building Resilience in a Hyper-Scaled Financial Pl...
"Scaling in space and time with Temporal", Andriy Lupa.pdf
"Database isolation: how we deal with hundreds of direct connections to the d...
"Scaling in space and time with Temporal", Andriy Lupa .pdf
"Provisioning via DOT-Chain: from catering to drone marketplaces", Volodymyr ...
" Observability with Elasticsearch: Best Practices for High-Load Platform", A...
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
"Istio Ambient Mesh in production: our way from Sidecar to Sidecar-less",Hlib...
Ad

Recently uploaded (20)

PPT
Teaching material agriculture food technology
PDF
cuic standard and advanced reporting.pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PPTX
Cloud computing and distributed systems.
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Teaching material agriculture food technology
cuic standard and advanced reporting.pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
Chapter 3 Spatial Domain Image Processing.pdf
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Cloud computing and distributed systems.
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
MIND Revenue Release Quarter 2 2025 Press Release
Per capita expenditure prediction using model stacking based on satellite ima...
Programs and apps: productivity, graphics, security and other tools
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
“AI and Expert System Decision Support & Business Intelligence Systems”
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Digital-Transformation-Roadmap-for-Companies.pptx
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Encapsulation_ Review paper, used for researhc scholars
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...

"Building intuitive command-line interfaces in .NET", Alex Thissen

  • 2. The rise of CLIs Graphical User Interface Command-line Interface Efficiency Fast and simple interaction model Low level access in single line commands Basic text-driven command line Automation Scriptable Integration in CI/CD pipelines Cross-platform Terminal-based or headless environments do not have GUI Allows porting to Windows, Linux and MacOS User experience Rich UI and UX Many visualizations
  • 3. Examples of CLIs and tools CLIs dotnet az docker kubectl tye git npm Tools curl python Interactive netsh mssql-cli telnet
  • 4. Demo Exploring CLIs Easter egg: Windows Terminal Quake Mode: + `
  • 5. Command syntax ale.exe .Zarlor.lnx --magnification 3 –f --controller keyboard Options - Key-value pairs - Short and long form names - Delimited by space, colon or equal sign - Style: POSIX -- or Windows / - Combine single char option - Arity Arguments - Required values in specific order - Arity (unary, binary, …)
  • 6. Command-line lifecycle Parsing and invoking Tokenization Value conversion Create context Execution Run middleware pipeline Handler run logic Building and preparing Define commands, arguments and options Configuration Input Command-line Response file Tab-completion Feedback Progress updates Prompting Rendering output Termination Exception handling Return exit codes Report errors Provide help and suggestions
  • 7. Host process Implementing CLIs in .NET Application code Recommended packages • System.CommandLine • CliFx • Spectre.Console.Cli • CommandLineParser Terminal or script
  • 8. System.CommandLine object model Prepare commands Build command-line Symbols Hierarchy of symbols Name (and aliases for identifier symbols) Other types Parse & Invoke
  • 9. Demo Building command-lines and parsers Create commands, arguments and options
  • 10. Command handling Provide handler function per command Create handler using factory methods Delegate or separate function Model binding used by default rootCommand.Handler = CommandHandler.Create<InvocationContext, int, bool>( (context, magnification, fullScreen) => { context.Console.Out.Write($"Magnification: {magnification} FullScreen {fullScreen}"); });
  • 11. Middleware pipeline ExceptionHandler Out-of-the-box 1. CancelOnProcessTermination 2. ExceptionHandler 3. EnvironmentVariableDirective 4. ConfigureConsole 5. RegisterWithDotnetSuggest 6. DebugDirective 7. ParseDirective 8. SuggestDirective Out-of-the-box 9. TypoCorrections 10. VersionOption 11. HelpOption Configuration Default ErrorReporting Your middleware logic Invocation context Out-of-the-box 12. ParseErrorReporting
  • 12. Registering middleware Extension methods on CommandLineBuilder Resembles ASP.NET Core middleware Various Use… methods Prioritize with MiddlewareOrder enumeration Parser parser = new CommandLineBuilder(rootCommand) .UseDefaults() .UseMiddleware(async (context, next) => { // Execute your middleware logic here await next(context); }, MiddlewareOrder.ErrorReporting) .Build(); Order of registration More than one custom middleware allowed Beware of defaults Production version might need to skip some default middleware (for example: directives)
  • 13. ale.exe .Zarlor.lnx –-full-screen -m 3 --controller keyboard Model binding Run(FileInfo gameRom, int magnification, bool fullScreen, ControllerType controller) In-order named arguments Named options Case insensitive Kebab casing supported Ignores hyphens and other prefixes Boolean, enumerations (case-insensitive) Enumerable types (arrays, lists, …) String based constructors (FileInfo, DirectoryInfo, Uri) Complex types (based on properties or constructor)
  • 14. Data types conversion Special types are bound automatically IConsole Abstraction for out and err ParseResult All results of parsing tokens command-line CancellationToken Cancel async tasks BindingContext Captures converted typed values InvocationContext Combines all of the above Run( … , ControllerType controller, BindingContext context, CancellationToken token) Simply add to command handler signature
  • 15. Demo: Advanced scenarios Error handling and termination Middleware Subcommands and global options Common patterns
  • 16. Making it intuitive Intuitive CLIs CLI-first approach Standards and conventions Simplicity Discoverability Offer help and documentation from CLI Defaults save time and better for learning Suggestions and typo corrections Familiar names of arguments and options Default to stderr and stdout First client application is a CLI More human-oriented: Ad-hoc tasks and quick Split a complex system into many small functions Assign each function into a simple command
  • 17. Help Get contextual help for free Description Available names Required and arity Allowed values and default value Provide custom help Create your own help builder Register with .UseHelp<THelpBuilder>
  • 18. Suggestions and typo corrections Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentSession dotnet tool install --global dotnet-suggest --version 1.1.221601 Terminal session Interactive Host process PowerShell bash zsh dotnet- suggest Global dotnet tool • Shell completions (aka tab completions) • Register small script in bash or PowerShell profile Suggestion sources • Enums and known values automatically added • Can add custom suggestions through ISuggestionSource Pro tip: DOTNET_SUGGEST_LOGGING 1 DOTNET_SUGGEST_SCRIPT_VERSION 1.0.1
  • 19. Debugging tips Use [debug] directive Attach debugger to start debug session from terminal Pass arguments from dotnet to your CLI { "profiles": { "AdvancedCLI": { "commandName": "Project", "commandLineArgs": "help", "environmentVariables": { "DOTNET_COMMANDLINE_DEBUG_PROCESSES": "ale" ale.exe [debug] .Zarlor.lnx --magnification 3 –f --controller keyboard dotnet run -- .Zarlor.lnx --magnification 3 –f --controller keyboard Possible error Debug directive specified, but no process names are listed as allowed for debug. Add your process name to the 'DOTNET_COMMANDLINE_DEBUG_PROCESSES' environment variable. The value of the variable should be the name of the processes, separated by a semi-colon ';', for example 'DOTNET_COMMANDLINE_DEBUG_PROCESSES=ale' Hint: Try [parse] and [suggest]
  • 20. Photo by Pavel Mata on Unsplash DragonFruit Quick and easy way to create a simple CLI Add reference to NuGet package System.CommandLine.DragonFruit Change Main method to include typed arguments Must return void, int, Task or Task<int> Provide XML documentation as help information static int Main(FileInfo gameRom, bool fullScreen = false, int magnification = 4, ControllerType controller = ControllerType.Keyboard, FileInfo bootRom = null) /// <summary> /// Atari Lynx Emulator from DragonFruit /// </summary> /// <param name="gameRom">Game ROM filename</param> /// <param name="fullScreen">Run emulator fullscreen</param>
  • 22. Console is not your average console Error, Out and In should be used Avoid System.Console Use provided abstraction instead (IConsole) TestConsole in unit tests Respect redirection Input might come from response file Output might be sent to file or elsewhere Test output with pipes Output and rendering Convenient: Include System.CommandLine.IO for extension methods on Error and Out
  • 23. Terminal GUIs for CLIs Rich interaction with user Remember: CLI != GUI
  • 24. Comparing CLI frameworks (opinionated) System.CommandLine Spectre.Console.Cli CommandLineParser CliFx Hierarchical commands Yes Yes Limited Yes Suggestions and typo corrections Yes No No No Help Autogenerated Autogenerated Autogenerated Autogenerated Target framework .NET Standard 2.0 .NET Standard 2.0 .NET 5.0 .NET Standard 2.0 .NET 4.0, 4.5, 4.6.1 .NET Standard 2.0, 2.1 Version 2.0.0-beta1.21308.1 0.49.0 2.9.0-preview1 2.0.6 Maintainer activity Binding ++ + + ++ Host integration ++ + - ++ Directives debug, parse, config None None debug, parse
  • 25. Summary {DevOps} $ CLI <3 .NET --always
  • 26. Questions and Answers During Discord Q&A session Maybe later? @alexthissen athissen@xpirit.com